Reputation: 1314
I have a function that takes two filenames, and reads the contents of those two files into String
s, and then returns if they match or not. Here's the function:
f :: String -> String -> IO Bool
f fileName1 fileName2 = do
str1 <- readFile fileName1
str2 <- readFile fileName2
return (str1 == str2)
And if I use it like this from inside main
:
main = do
res <- f "A.txt" "B.txt"
print res
It works and prints either True
or False
. What I want to do is, apply this function f
to a list (of tuples) of filenames. For something like:
[("a.txt", "b.txt"), ("c.txt", "d.txt")]
(Assume that a.txt
and b.txt
have the same content and c.txt
and d.txt
are different).
I want to transform it (the list of file names) into a Bool
list like: [True, False]
. I tried using mapM
, but that doesn't appear to map anything (when I print the list after using mapM
, it prints the same list of tuples).
So my question is: What am I doing wrong, and how can I get a list of Bool
s like I mentioned above?
Please go easy on me as I'm still quite new to Haskell and functional programming :)
Upvotes: 0
Views: 753
Reputation: 32319
Here is a function f'
which does what you describe.
f' :: [(String,String)] -> IO [Bool]
f' = mapM $ uncurry f
Let me know if something is unclear! And, just to be clear, here is how you run it:
main = do
res <- f' [("a.txt", "b.txt"), ("c.txt", "d.txt")]
print res
The function is in pointfree form, so it is equivalent to f' lst = mapM (uncurry f) lst
. mapM
essentially maps each element of lst
using f
as the function, and pushes the IO
to the outside of the list.
uncurry
just takes a function of the form a -> b -> c
and transforms it into one (a,b) -> c
, which is what we want since you have a list of tuples.
Upvotes: 2