Concise if-then-else notation in do-blocks in Haskell
Asked Answered
D

4

13

I cannot figure out how to make the concise if-then-else notation work, mentioned at [ http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse ]. This works,

import System.Environment
main = do
    args <- getArgs
    if (args !! 0) == "hello"
        then
            print "hello"
        else
            print "goodbye"

but this does not, and inserting said semicolons (see link) just result in parse errors for me.

import System.Environment
main = do
    args <- getArgs
    if (args !! 0) == "hello" then
        print "hello"
    else
        print "goodbye"
Deictic answered 24/5, 2011 at 22:35 Comment(6)
What version of GHC are you using? - or, are you using GHC? :)Bulletin
6.12.3 (unfortunately, the OpenSuSE binaries are rather out of date)Deictic
Why are you separating your then and else from their lines?Chole
Unfortunately it was fixed in 6.13.Bulletin
I know you probably used it as a toy example, but nitpicking reveals you could have used: print $ if head args == "hello" then "hello" else "goodbye"Alpestrine
@mathepic Though it looks incongruent, this is useful for decreasing indentation, especially when one needs to make the then/else blocks do blocks (you can just add "do" after "then" and "else")Deictic
F
12

The link you provided describes a proposal, which sounds like it is not part of the Haskell standard (although the link mentions that it's implemented in jhc, GHC and Hugs). It's possible that the version of the Haskell compiler you're using, or the set of flags you're using, does not allow for the optional-semicolon behavior described in the link.

Try this:

import System.Environment
main = do
    args <- getArgs
    if (args !! 0) == "hello" then
        print "hello"
        else
            print "goodbye"
Fennelly answered 24/5, 2011 at 22:42 Comment(2)
The proposal was accepted into Haskell 2010. It works without changes on GHC 7.0.2.Wesle
Oh! Good to know! It's possible that gatoatigrado was using an older version of GHC without support for that.Fennelly
C
5

In Haskell 98 “if … then … else …” is a single expression. If it’s split to multiple lines, the ones following the first one must be indented further.

Just like the following is wrong…

do
  1 +
  2

…and the following works…

do
  1 +
    2

…the following is also wrong…

do
  if True then 1
  else 2

…and the following works.

do
  if True then 1
    else 2

As the other comments already mention, Haskell 2010 allows the “then” and “else” parts on the same level of indentation as the “if” part.

Cubical answered 24/5, 2011 at 23:47 Comment(0)
Q
3

Haskell syntax and language are extended though {-# LANGUAGE ... #-} pragmas at the start of the source files. The DoAndIfThenElse extension is recognized since it is one of those listed in the Cabal documentation. Current GHC enables this by default.

Quad answered 25/5, 2011 at 11:22 Comment(0)
P
2

I usually indent the else one space more than the if. Unless then whole if fits nicely on a single line.

Polysynthetic answered 24/5, 2011 at 23:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.