【问题标题】:Mapping with IO actions in Haskell在 Haskell 中使用 IO 操作进行映射
【发布时间】:2015-06-20 20:53:37
【问题描述】:

我有一个函数,它接受两个文件名,并将这两个文件的内容读入Strings,然后如果它们匹配则返回。函数如下:

f :: String -> String -> IO Bool
f fileName1 fileName2 = do
        str1 <- readFile fileName1
        str2 <- readFile fileName2
        return (str1 == str2)

如果我从main内部这样使用它:

main = do
        res <- f "A.txt" "B.txt"
        print res

它可以工作并打印TrueFalse。我想要做的是,将此函数f 应用于文件名列表(元组)。对于类似的东西:

[("a.txt", "b.txt"), ("c.txt", "d.txt")]

(假设a.txtb.txt内容相同,c.txtd.txt不同)。

我想将它(文件名列表)转换为Bool 列表,例如:[True, False]。我尝试使用mapM,但这似乎没有映射任何内容(当我在使用mapM 后打印列表时,它会打印相同的元组列表)。

所以我的问题是:我做错了什么,我怎样才能得到上面提到的Bools 的列表?

请放轻松,因为我对 Haskell 和函数式编程还是很陌生 :)

【问题讨论】:

  • 您的mapM 代码是什么样的?
  • @DavidYoung mapM (\(a, b) -&gt; f a b) lstlst 是我在上面发布的元组列表

标签: list haskell io


【解决方案1】:

这是一个函数f',它可以按照您的描述进行操作。

f' :: [(String,String)] -> IO [Bool]
f' = mapM $ uncurry f

如果有什么不清楚的地方请告诉我!而且,为了清楚起见,以下是您的运行方式:

main = do
        res <- f' [("a.txt", "b.txt"), ("c.txt", "d.txt")]
        print res

编辑

函数是无点形式的,所以它等价于f' lst = mapM (uncurry f) lstmapM 实质上使用f 作为函数映射lst 的每个元素,并将IO 推到列表外部。

uncurry 只是采用a -&gt; b -&gt; c 形式的函数并将其转换为(a,b) -&gt; c,这是我们想要的,因为您有一个元组列表。

【讨论】:

  • 成功了!谢谢 :) 但是你能解释一下uncurry 的使用吗?而这背后到底发生了什么?mapM
  • 知道了 :) 再次感谢您的回答的解释。我不确定mapMuncurry 是如何工作的,不过现在还可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多