Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concise if-then-else notation in do-blocks in Haskell

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"
like image 212
gatoatigrado Avatar asked May 24 '11 22:05

gatoatigrado


4 Answers

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.

like image 164
ion Avatar answered Nov 07 '22 16:11

ion


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.

like image 32
Chris Kuklewicz Avatar answered Nov 07 '22 15:11

Chris Kuklewicz


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"
like image 12
Zach Avatar answered Nov 07 '22 16:11

Zach


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

like image 2
augustss Avatar answered Nov 07 '22 17:11

augustss