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在一个then或else 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)
使用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)
对此的规范解释是,您希望从两个现有值中形成新的monadic值.我们来看看putStr的类型,
IO ()
Run Code Online (Sandbox Code Playgroud)
这意味着它是一个黑盒子,在执行时,将"返回"单位类型的(一个也是唯一的)值.monadic计算背后的关键思想是你有一个组合器>>=,它将两个monadic表达式放在一起,将一个结果输入下一个(更准确地说,是一个创建下一个的函数).一个关键点是IO库提供了这个组合器,意思是,
IO的RealWorld状态的情况下,它可以传递其他数据.在你的情况下,像这样使用它,
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)
对于这个人为的示例,您不妨使用一个案例,如下所示:
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)