Boyd Crowder
Boyd Crowder

Reputation: 11

Parse Error: Haskell

I am getting a parse error on the below and I'm not sure why. Thanks for any help!

   createObject :: [a] -> object a 
   createObject lst =
      let x = lst !! 0
      let y = lst !! 1
      let z = lst !! 2
      in object(x,y,z)

   test.hs:28:5: error: parse error on input `let'
   |
   28 |     let y = lst !! 1

Upvotes: 1

Views: 134

Answers (2)

chi
chi

Reputation: 116139

Each let must have its own in (except in do notation and list comprehensions).

You could therefore use

createObject lst =
      let x = lst !! 0
      in let y = lst !! 1
      in let z = lst !! 2
      in object(x,y,z)

but this is not idiomatic, since a single let can involve a block of definitions. Indeed, @jkeuhlen showed above the idiomatic use of let.

You should however avoid using !!, which is slow and partial, and prefer pattern matching whenever possible.

createObject :: [a] -> object a 
createObject [x,y,z] = object (x,y,z)
createObject _       = error "createObject: input list must have length 3"

or

createObject :: [a] -> object a 
createObject (x:y:z:_) = object (x,y,z)
createObject _         = error "createObject: input list must have length >= 3"

Note that the above is still a code smell: the input type [a] looks wrong, since it seems to allow any list length, when it actually works only on length 3 (or larger, in the second case, ignoring the other elements).

It is hard to guess what you actually need, here.

Upvotes: 1

jkeuhlen
jkeuhlen

Reputation: 4507

let-in expressions in Haskell use only one let:

createObject :: [a] -> object a 
createObject lst =
  let x = lst !! 0
      y = lst !! 1
      z = lst !! 2
  in object(x,y,z)

In a do block, you do use multiple let bindings, but we don't use an in expression:

trivialExample :: [a] -> IO (Object a)
trivialExample lst = do 
  let x = lst !! 0 
  let y = lst !! 1 
  let z = lst !! 2
  return $ object (x,y,z)

Upvotes: 8

Related Questions