Haskell左箭头运算符替代

我一般是 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函数的用武之地。在这种情况下,我们只需要考虑具有 type 的专用版本[IO String] -> IO [String]

content <- sequence [readFile f | f <- filenames]

我们也可以使用traverse,特别是带有 type 的专用版本(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)

我们使用[]as our Traversable,和IO我们的Monad/ Applicative

  • I'd also mention `mapM`, which is (now) equivalent to `traverse`, and its flipped version `forM`, which often makes for more readable code (`forM fileNames $ f -> do {multiple IO statements involving f}`).

以上是Haskell左箭头运算符替代的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>