我有一个带有两个文件名的函数,并将这两个文件的内容读入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
它工作并打印True
或False
。我想要做的是,将此函数f
应用于文件名列表(元组)。对于类似的事情:
[("a.txt", "b.txt"), ("c.txt", "d.txt")]
(假设a.txt
和b.txt
内容相同且c.txt
和d.txt
不同。
我想将它(文件名列表)转换为Bool
列表,如:[True, False]
。我尝试使用mapM
,但似乎没有映射任何内容(当我使用mapM
后打印列表时,它会打印相同的元组列表。)
所以我的问题是:我做错了什么,如何获得像上面提到的Bool
列表?
请放轻松我,因为我对Haskell和函数式编程还很陌生:)
答案 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) lst
。 mapM
基本上使用lst
作为函数映射f
的每个元素,并将IO
推送到列表的外部。
uncurry
只需使用a -> b -> c
形式的函数并将其转换为一个(a,b) -> c
,这就是我们想要的,因为您有一个元组列表。