我发现了以下Haskell代码,但我很困惑:
main = putStrLn "Enter 1st String:"
>> getLine
>>= \a -> read a
两个“大于”符号(>>
)是什么意思?新声明?
两个“大于”符号后跟一个等号(>>=
)是什么意思?
此Haskell代码抛出以下错误:
a.hs:3:13:
No instance for (Read (IO t0)) arising from a use of ‘read’
In the expression: read a
In the second argument of ‘(>>=)’, namely ‘\ a -> read a’
In the expression:
putStrLn "Enter 1st String:" >> getLine >>= \ a -> read a
答案 0 :(得分:5)
1)两个大于符号的意思是一个新的陈述吗?
在这种情况下,是的。在IO monad中,>>
与许多命令式编程语言中的;
大致相同。
2)两个大于符号后跟等号的意思是什么?
x >>= y
与x >> y
类似,只是它取x
的结果并适用于y
,它必须是一个函数。简而言之,getLine >>= \a -> action
表示“读取一行,将该值绑定到变量a
,然后运行action
(可能取决于a
)。
我建议使用monad教程来完全理解这些。您可以从一般教程开始,例如LYAH。
您的代码更常用do
符号编写:
main = do
putStrLn "Enter 1st String:"
a <- getLine
read a
最后一行没有意义:read
返回一个值但不执行任何I / O,因此我们无法将其链接到一系列I / O操作。这会触发编译器错误。如果您了解一些命令式编程,请考虑伪代码
print("some message");
a = inputLine();
toInteger(a);
最后一行没有意义:它将字符串转换为整数...然后不以任何方式使用结果。
答案 1 :(得分:2)
关于您的第二个问题:您的main
不是有效的monadic表达式。当专门用于IO
monad时, bind 和然后运算符具有类型
(>>=) :: IO a -> (a -> IO b) -> IO b
(>>) :: IO a -> IO b -> IO b
如果您尝试对齐main
表达式的类型,您将很快发现问题:
putStrLn "Enter 1st String:" >> getLine >>= \a -> read a
{ IO () } {IO String} {actual: Read t => String -> t }
{ IO String } {expected: String -> IO t} ??? }
>>=
的第二个参数的预期类型为String -> IO t
,但read
不会返回IO
值。