1
if even 2 then 10 else 11 -- works fine

if even 2 then let t = 10 else let s = 11 -- _:27: parse error on input 'else'

if even 2 then 10 else let s = 11 -- _:34 parse error (possibly incorrect indentation or mismatched brackets)

because let's say I want to code something like this with [[p]]:

[ t | let e = [], 
      let o = p!!14, r <- [13,12..1], 
      if even r 
      then 
         let o = zipWith (+) (p!!r) (zipWith max e (drop 1 e))
             t = o
      else 
         e = zipWith (+) (p!!r) (zipWith max o (drop 1 o))
      t = e ]

which at load time reports the error . . . _:33: parse error on input `else'

1
  • 7
    You really need to go through a proper introductory Haskell tutorial. Please don't assume that Haskell is like every other language, like your python like list comprehensions. Oh and one other thing, welcome to SO! Commented Jan 9, 2014 at 6:28

3 Answers 3

6

You seem to be assigning different values to a binding in different branches in an imperative way. This doesn't work in Haskell, you must instead of the conditional inside the assignment of the binding like so:

[ t | let e = [],
      let o = p!!14,
      r <- [13,12..1],
      let t = if even r
              then zipWith (+) (p!!r) (zipWith max e (drop 1 e))
              else zipWith (+) (p!!r) (zipWith max o (drop 1 o))
]

Note that the if has to line up. It must either start on the same line as the = or it must be at the same or greater indentation level as the = on the following line.

Another thing I notice is that e will always be [] and I imagine this wasn't the intention.

Sign up to request clarification or add additional context in comments.

1 Comment

If/then/else isn't subject to indentation (it has keywords separating every part, so it doesn't need indentation to determine where parts begin). The only indentation-sensitive construction here is let, which does mean that all of the if/then/else must be on lines indented more than the t (no matter how the lines are indented relative to each other). The position of the = isn't relevant to anything.
0

The then and the else part in an if expression should return the same type in Haskell.

It's syntax is like this:

if <condition> then <true-value> else <false-value>\

In your example, there is no point of using let unless you are planning to use that variable in the if conditional itself.

LYAH book nicely points out the difference of If conditional as compared to imperative languages:

The difference between Haskell's if statement and if statements in imperative languages is that the else part is mandatory in Haskell. In imperative languages you can just skip a couple of steps if the condition isn't satisfied but in Haskell every expression and function must return something.

Comments

-1
then 
     let o = zipWith (+) (p!!r) (zipWith max e (drop 1 e))
         t = o

"in" keyword must be after "let" expression

1 Comment

This is inside a list comprehension, which means you don't have the in after the let expression. In this way, it is similar to a do block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.