Haskell 左箭头运算符替代

Haskell left arrow operator alternative

我是 haskell 和一般函数式编程的新手,我对 monad 有疑问。假设我有一个文件名列表:

-- do block --
let filenames = ["file1","file2"]

我想使用列表推导生成这些文件内容的列表:

let content = [str <- readFile f | f <- filenames]

Ofc,这种用法是无效的。 据我了解,当将结果与下一条指令“链接”时,可以在 do 块中使用这种“赋值”。

是否有其他方法可以使用左箭头(或 >>=)运算符。我想象这样的事情:

let content = [leftArrAlter $ readFile f | f <- filenames]

让我们从更简单的列表开始

let content = [readFile f | f <- filenames]

content 的类型为 [IO String];它是 IO 个动作的列表,每个动作在执行时都可以产生一个 String

您想要的是 IO [String] 类型的内容:单个 IO 操作,执行时会为您提供 String 个值的列表。

这就是 sequence 函数的用武之地。在这种情况下,我们只需要考虑类型为 [IO String] -> IO [String]:

的专用版本
content <- sequence [readFile f | f <- filenames]

我们也可以使用 traverse,特别是类型为 (FilePath -> IO String) -> [FilePath] -> IO [String]:

的专用版本
content <- traverse readFile fileNames

两个函数的大致类型供参考:

sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

我们用[]作为我们的TraversableIO作为我们的Monad/Applicative