使用函数getLine.
它有一种类型
getLine :: IO String
Run Code Online (Sandbox Code Playgroud)
如何从此IO值中提取String.更一般地说,我该如何转换它.
IO a
Run Code Online (Sandbox Code Playgroud)
对此:
a
Run Code Online (Sandbox Code Playgroud)
如果这是不可能的.为什么我不能这样做?
dan*_*iaz 10
在Haskell中,当您想要使用"陷入" IO
的值时,您不会从中获取值IO
.相反,您也要将要执行的操作放入其中IO
!
例如,假设您要getLine :: IO String
使用length
Prelude中的函数来检查将产生多少个字符.
存在一个辅助函数fmap
,当专门用于时IO
,具有以下类型:
fmap :: (a -> b) -> IO a -> IO b
Run Code Online (Sandbox Code Playgroud)
它需要一个可以处理未被捕获的"纯"值IO
的函数,并为您提供一个函数,该函数可以处理陷入的值IO
.这意味着代码
fmap length getLine :: IO Int
Run Code Online (Sandbox Code Playgroud)
表示IO
从控制台读取一行的动作,然后为您提供其长度.
<$>
是一个中缀的同义词fmap
,可以使事情变得更简单.这相当于上面的代码:
length <$> getLine
Run Code Online (Sandbox Code Playgroud)
现在,有时操作要与执行IO
-trapped值本身返回IO
-trapped值.简单的例子:你要写回你刚读过的字符串putStrLn :: String -> IO ()
.
在那种情况下,fmap
还不够.您需要使用(>>=)
运算符,该运算符在特殊情况下IO
具有该类型IO a -> (a -> IO b) -> IO b
.在外面的情况:
getLine >>= putStrLn :: IO ()
Run Code Online (Sandbox Code Playgroud)
使用(>>=)
链式IO
动作具有必要的顺序风格.有一种叫做"do-notation"的语法糖,它有助于以更自然的方式编写这样的顺序操作:
do line <- getLine
putStrLn line
Run Code Online (Sandbox Code Playgroud)
请注意,<-
这里不是运算符,而是由符号提供的语法糖的一部分.