Haskell IF остальное - PullRequest
       51

Haskell IF остальное

4 голосов
/ 08 июня 2011
input <- readLn
 if (input == 0)
 then 
  putStr  "0" 
 else if (input ==1)
then 
  putStr  "1" 
else if (input ==2)

в этом типе senario, как использовать несколько putStr в then или else if?

, когда я пытаюсь получить ошибку

Type error in application
*** Expression     : putStr "0" putStr "0"
*** Term           : putStr
*** Type           : String -> IO ()
*** Does not match : a -> b -> c -> d

Ответы [ 3 ]

8 голосов
/ 08 июня 2011

Использовать do -обозначение:

do
  a <- something
  if a 
  then
    do
      cmd1
      cmd2
  else
    do
      cmd3
      cmd4
  cmd5 -- this comes after the 'then' and the 'else'
6 голосов
/ 08 июня 2011

Каноническое объяснение этого заключается в том, что вы хотите сформировать новое монадическое значение из двух существующих.Давайте посмотрим на тип putStr,

IO ()

Это означает, что это какой-то черный ящик, который при выполнении будет «возвращать» (единственное) значение типа блока.Основная идея монадических вычислений заключается в том, что у вас есть комбинатор >>=, который объединит два монадических выражения, передавая результат одного в другое (точнее, функцию, которая создает следующее).Одним из важных моментов является то, что библиотека IO предоставляет этот комбинатор , что означает, что

  • Это [IO в этом случае] может пропускать второе монадическое значение, например, когдапервый вызывает исключение.
  • Может передавать другие данные, в случае IO a RealWorld состояния, содержащего дескрипторы открытого файла и т. д.
  • Он может «гарантировать», чтопервый оценивает первый, в отличие от большинства вычислений лямбда-выражений, где самые внешние («последние») термины расширяются первыми.Это важно для печати, где первый отпечаток должен изменить мир первым.

В вашем случае используйте его следующим образом:

putStr "0" >>= (\c -> putStr "0")

Есть, конечно, ярлык,

putStr "0" >> putStr "0"

и примечание do, как упомянуто другим автором, которое является еще более синтаксическим сахаром,

do
    putStr "0"
    putStr "0"
4 голосов
/ 08 июня 2011

Для этого надуманного примера вы также можете использовать кейс, например так:

main = readLn >>= \input -> case input of
    0 ->    putStrLn "0"

    1 ->    putStrLn "0"

    2 ->    putStr   "0" 
         >> putStrLn "0"

    3 ->    putStr   "0"
         >> putStr   "0"
         >> putStrLn "0"

    _ ->    putStrLn "infinite"

Возможно, это может быть более читабельно при использовании синтаксиса do, но я хотел сначала показать его без синтаксиса do, просто чтобы подчеркнуть, что do-syntax - это всего лишь синтаксис и на самом деле не делает ничего особенного. Вот он с do-синтаксисом.

main = do
    input <- readLn
    case input of
        0 -> putStrLn "0"

        1 -> putStrLn "0"

        2 -> do putStr   "0" 
                putStrLn "0"

        3 -> do putStr   "0"
                putStr   "0"
                putStrLn "0"

        _ -> putStrLn "infinite"
...