简体   繁体   中英

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 ?

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
  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,

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). One critical point is that the IO library provides this combinator , meaning that,

  • It [IO in this case] could skip the second monadic value, for example when the first one throws an exception.
  • It can pass other data around, in the case of IO a RealWorld state containing open file handles, etc.
  • It can "ensure" that the first one evaluates first, unlike most lambda expression evaluations, where the outermost ("last") terms are expanded first. 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
    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. Here it is with 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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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