在Haskell中使用IO操作进行映射

时间:2015-06-20 20:53:37

标签: list haskell io

我有一个带有两个文件名的函数,并将这两个文件的内容读入String s,然后返回它们是否匹配。这是功能:

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后打印列表时,它会打印相同的元组列表。)

所以我的问题是:我做错了什么,如何获得像上面提到的Bool列表?

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

1 个答案:

答案 0 :(得分:2)

这是一个函数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基本上使用lst作为函数映射f的每个元素,并将IO推送到列表的外部。

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