I need some help with types in Haskell...
Here's the code I'm working on:
loadManyPeople :: [FilePath] → IO [Person]
loadManyPeople fs = do
return $ concat $ map loadPeople fs
loadPeople :: FilePath → IO [Person]
loadPeople file = do
lines ← getLines file
return $ map parsePerson lines
loadPeople is fine. I want loadManyPeople to load all the Persons from each file, then concat them into one list of Persons.
I'm new to Haskell and need help with getting the types to work out.
Thanks for the help. Alex
loadPeople
gives you an IO [Person]
, so map loadPeople
gives you a [IO [Person]]
, however to use concat
, you'd need a [[Person]]
.
To fix this, you can use sequence, which is a function of type [IO a] -> IO [a]
, so you can do the following:
loadManyPeople fs = do
manyPeople <- sequence $ map loadPeople fs
return $ concat manyPeople
However there's a shortcut for using map
and then sequence
: mapM
which has type (a -> IO b) -> [a] -> IO [b]
. With mapM
your code looks like this:
loadManyPeople fs = do
manyPeople <- mapM loadPeople fs
return $ concat manyPeople
This can be written more succinctly using Applicative:
import Control.Applicative
loadManyPeople fs = concat <$> mapM loadPeople fs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With