Haskell 中的 IO 操作映射
Mapping with IO actions in Haskell
我有一个函数,它接受两个文件名,并将这两个文件的内容读入 String
s,然后 returns 如果它们匹配或不匹配。这是函数:
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 和函数式编程还很陌生 :)
这是一个函数 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
实质上是使用 f
作为函数映射 lst
的每个元素,并将 IO
推到列表外部。
uncurry
只是采用 a -> b -> c
形式的函数并将其转换为一个 (a,b) -> c
,这是我们想要的,因为您有一个元组列表。
我有一个函数,它接受两个文件名,并将这两个文件的内容读入 String
s,然后 returns 如果它们匹配或不匹配。这是函数:
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 和函数式编程还很陌生 :)
这是一个函数 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
实质上是使用 f
作为函数映射 lst
的每个元素,并将 IO
推到列表外部。
uncurry
只是采用 a -> b -> c
形式的函数并将其转换为一个 (a,b) -> c
,这是我们想要的,因为您有一个元组列表。