简体   繁体   中英

Mapping with IO actions in Haskell

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 :)

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

EDIT

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM