简体   繁体   English

Haskell IF 否则

[英]Haskell IF Else

input <- readLn
 if (input == 0)
 then 
  putStr  "0" 
 else if (input ==1)
then 
  putStr  "1" 
else if (input ==2)

in this kind of senario how to use multiple putStr with in a then or else if ?在这种情况下,如何在thenelse if中使用多个 putStr?

when i try getting a error当我尝试出错时

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

Use do -notation:使用do表示法:

do
  a <- something
  if a 
  then
    do
      cmd1
      cmd2
  else
    do
      cmd3
      cmd4
  cmd5 -- this comes after the 'then' and the 'else'

The canonical explanation for this is that you want to form a new monadic value out of two existing ones.对此的规范解释是,您想从两个现有的一元值中形成一个新的一元值。 Let's look at the type of putStr,我们来看看 putStr 的类型,

IO ()

That means it's some black box, that when executed, will "return" the (one-and-only) value of unit type.这意味着它是一个黑匣子,在执行时将“返回”单元类型的(唯一的)值。 The key idea behind monadic computation is that you have a combinator >>= which will put together two monadic expressions, feeding the result of one into the next (more accurately, a function that creates the next).一元计算背后的关键思想是你有一个组合器>>=它将组合两个一元表达式,将一个的结果输入下一个(更准确地说,一个创建下一个的 function)。 One critical point is that the IO library provides this combinator , meaning that,一个关键点是IO提供了这个组合器,这意味着,

  • It [IO in this case] could skip the second monadic value, for example when the first one throws an exception.它 [IO 在这种情况下] 可以跳过第二个单子值,例如当第一个抛出异常时。
  • It can pass other data around, in the case of IO a RealWorld state containing open file handles, etc.它可以传递其他数据,在IO的情况下, RealWorld state 包含打开的文件句柄等。
  • It can "ensure" that the first one evaluates first, unlike most lambda expression evaluations, where the outermost ("last") terms are expanded first.它可以“确保”第一个首先评估,这与大多数 lambda 表达式评估不同,其中最外层(“最后”)项首先展开。 This is important for print, where the first print needs to change the world first.这对印刷很重要,因为第一次印刷需要首先改变世界。

In your case, use it like this,在你的情况下,像这样使用它,

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

There's a shortcut, of course,当然有捷径

putStr "0" >> putStr "0"

and the do-notation, as mentioned by another poster, which is yet more syntax sugar,还有 do-notation,正如另一张海报所提到的,它更像是语法糖,

do
    putStr "0"
    putStr "0"

For this contrived example, you may as well use a case, like this:对于这个人为的示例,您也可以使用一个案例,如下所示:

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"

This could be perhaps be more readable with do syntax, but I wanted to show it without do syntax first, just to emphasize that do-syntax is just syntax and doesn't actually do anything special.使用 do 语法可能更易于阅读,但我想先不使用 do 语法来展示它,只是为了强调 do-syntax 只是语法,实际上并没有做任何特别的事情。 Here it is with 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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM