获取并在Haskell中放入一个字符串会引发错误

时间:2015-03-22 09:32:38

标签: haskell ghc

我发现了以下Haskell代码,但我很困惑:

main = putStrLn "Enter 1st String:"  
  >> getLine
  >>= \a -> read a
  1. 两个“大于”符号(>>)是什么意思?新声明?

  2. 两个“大于”符号后跟一个等号(>>=)是什么意思?

  3. 此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
    

2 个答案:

答案 0 :(得分:5)

  

1)两个大于符号的意思是一个新的陈述吗?

在这种情况下,是的。在IO monad中,>>与许多命令式编程语言中的;大致相同。

  

2)两个大于符号后跟等号的意思是什么?

x >>= yx >> 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值。