Haskell IF Else

Sud*_*ha 4 monads haskell if-statement do-notation

input <- readLn
 if (input == 0)
 then 
  putStr  "0" 
 else if (input ==1)
then 
  putStr  "1" 
else if (input ==2)
Run Code Online (Sandbox Code Playgroud)

在这种情况下如何使用多个putStr在一个thenelse if

当我尝试收到错误

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

Lam*_*eek 8

使用do注释:

do
  a <- something
  if a 
  then
    do
      cmd1
      cmd2
  else
    do
      cmd3
      cmd4
  cmd5 -- this comes after the 'then' and the 'else'
Run Code Online (Sandbox Code Playgroud)

  • @FUZxxl对,我也是.但我想强调的是,它不是一些神奇的"然后做"语法.它只是`if-then-else`表达式分支内的正常`do`-notation. (3认同)

gat*_*ado 6

对此的规范解释是,您希望从两个现有值中形成新的monadic值.我们来看看putStr的类型,

IO ()
Run Code Online (Sandbox Code Playgroud)

这意味着它是一个黑盒子,在执行时,将"返回"单位类型的(一个也是唯一的)值.monadic计算背后的关键思想是你有一个组合器>>=,它将两个monadic表达式放在一起,将一个结果输入下一个(更准确地说,是一个创建下一个的函数).一个关键点是IO提供了这个组合器,意思是,

  • 它[在这种情况下为IO]可以跳过第二个monadic值,例如当第一个抛出异常时.
  • 在包含打开文件句柄等IORealWorld状态的情况下,它可以传递其他数据.
  • 它可以"确保"第一个首先进行评估,这与大多数lambda表达式评估不同,其中最外层("最后")术语首先被扩展.这对于印刷很重要,因为第一印刷需要首先改变世界.

在你的情况下,像这样使用它,

putStr "0" >>= (\c -> putStr "0")
Run Code Online (Sandbox Code Playgroud)

当然,有一条捷径

putStr "0" >> putStr "0"
Run Code Online (Sandbox Code Playgroud)

和另一张海报所提到的记号,这是更多的语法糖,

do
    putStr "0"
    putStr "0"
Run Code Online (Sandbox Code Playgroud)


Bar*_*ter 5

对于这个人为的示例,您不妨使用一个案例,如下所示:

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"
Run Code Online (Sandbox Code Playgroud)

这可能使用 do 语法更具可读性,但我想先不使用 do 语法来展示它,只是为了强调 do-syntax 只是语法,实际上并没有做任何特殊的事情。这里是 do-syntax。

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"
Run Code Online (Sandbox Code Playgroud)