我正在使用Haskell中提供的readFile
函数从文件中读取一些数据。但是这个函数会返回一些存储为IO String
的数据。有没有人知道如何将这些数据转换为String
类型(或从文件中读取String
的任何函数,而不是IO ()
类型)?
答案 0 :(得分:18)
关于从monadic值中提取数据这是一个非常普遍的问题。
一般的想法是使用>>=
函数:
main = readFile foo >>= \s -> print s
>>=
有2个参数。它从第一个参数中提取值并将其传递给第二个参数。第一个参数是monadic值,在这种情况下类型为IO String
,第二个参数是一个接受普通非monadic值的函数,在本例中为String
。
此模式有一种特殊语法:
main = do
s <- readFile foo
print s
但其含义与上述相同。对于初学者和某些复杂的情况,do
表示法更方便,但明确应用>>=
可以缩短代码。例如,此代码可以写为
main = readFile foo >>= print
还有一大类库函数可以在monadic和非monadic值之间进行转换。其中最重要的是return
,fmap
,liftM2
和>=>
。
monad的概念除了以引用透明的方式表示IO之外非常有用:这些帮助程序对于错误处理非常有用,处理隐式状态和monad的其他应用程序。
第二个最重要的单子是Maybe
。
答案 1 :(得分:1)
在这种情况下,我会将IO类型视为functor,而不是从中获取值,我会在其中发送我的函数并让Functor
实例处理使用我的函数创建一个新的IO容器。
> :m +Data.Functor
> length <$> readFile "file.txt"
525
<$>
是fmap
的别名。我更喜欢<$>
,但这只是个人偏好。