简体   繁体   中英

Haskell if then else parse error on input `else'

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'

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.

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.

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

"in" keyword must be after "let" expression

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM