elliptic00
elliptic00

Reputation: 447

Haskell, can not resolve type issue: Data.Vector.zip fromList[1..10] fromList[1..10]

When I run

let v = Data.Vector.zip fromList[1..10] fromList[2..11]

I got error:

Couldn't match expected type ‘Vector b0’ with actual type ‘[Integer]’

Instead I have to do like that:

let v1 = fromList[1..10]
let v2 = fromList[2..11]
let v = Data.Vector.zip v1 v2

fromList is Vector type in Data.Vector

Can anyone explain to me why fromList[1..10] can not be converted to Vector type in Data.Vector? and I have to create v1 and v2?

Upvotes: 0

Views: 74

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120711

First, let's

import qualified Data.Vector as V

to avoid having to type out Data.Vector.zip.


Haskell's parsing rules often stump beginners, but frankly I think this is more because they're too simple rather than too strange. In brief:

  1. parentheses / brackets only group their contents, they never influence anything outside. So, f(x), (f)x and (f) (x) are all the same, preferrably written just f x.
  2. Infix operators bind less tightly than any function application.
  3. Function application greedily gathers everything from left to right.

How much whitespace you put between two tokens is not considered by the parser at all.

So in your example, we can

  1. give the list definitions local names:

    l₁ = [1..10]
    l₂ = [2..11]
    v = V.zip fromList l₁ fromList l₂
    
  2. There are no infix operators here.

  3. Greedily gather arguments:

    v = (V.zip fromList) l₁ fromList l₂
      = ((V.zip fromList) l₁) fromList l₂
      = (((V.zip fromList) l₁) fromList) l₂
    

    Un-curried languages would write this as zip(fromList, l₁, fromList, l₂), and that's clearly not what you want.

The most direct way to get around this is to parenthesise:

v = V.zip (fromList [1..10]) (fromList [2..11])

...or give the packed vectors names of their own

v₁ = fromList [1..10]
v₂ = fromList [2..11]
v = V.zip l₁ l₂

...or avoid writing fromList entirely:

{-# LANGUAGE OverloadedLists #-}

v :: V.Vector Int
v = V.zip [1..10] [2..11]

You may wonder what's up with the . in Data.Vector.zip. That's not the infix operator . but the module qualifier symbol. This is one of only two “infix symbols” with a special parsing rule (the other being the unary minus): anything of the form Foo.bar (with uppercase Foo and no whitespace!) is recognised as a single token bar coming from module Foo.

Upvotes: 4

Related Questions