Краткая запись if-then-else в do-block в Haskell

Я не могу понять, как сделать краткую нотную работу if-then-else, упомянутую в [http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse]. Это работает,

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

но это не так, и вставка указанных точек с запятой (см. ссылку) просто приводит к ошибкам разбора для меня.

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

Ответы

Ответ 1

Указанная вами ссылка описывает предложение, которое звучит так, будто оно не является частью стандарта Haskell (хотя ссылка упоминает, что она реализована в jhc, GHC и Hugs). Возможно, что версия используемого вами компилятора Haskell или набор флагов, которые вы используете, не допускает поведения с опцией-точкой с запятой, описанной в ссылке.

Попробуйте следующее:

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

Ответ 2

В Haskell 98 "if... then... else..." одно выражение. Если его разделение на несколько строк, те, которые следуют за первым, должны быть отступы дальше.

Так же, как следующее неверно...

do
  1 +
  2

... и следующие работы...

do
  1 +
    2

... следующее также неверно...

do
  if True then 1
  else 2

... и следующие работы.

do
  if True then 1
    else 2

Как уже упоминалось в других комментариях, Haskell 2010 разрешает части "then" и "else" на том же уровне отступов, что и "если" часть.

Ответ 3

Синтаксис и язык Haskell расширены, хотя {- # LANGUAGE... # -} прагмы в начале исходных файлов. Расширение DoAndIfThenElse распознается, поскольку оно является одним из перечисленных в документации Cabal. Текущий GHC позволяет это по умолчанию.

Ответ 4

Я обычно выделяю else на одно место больше, чем if. Если тогда целое if прекрасно подходит для одной строки.