I'm still figuring out Haskell, especially the IO monad.
I have a list of directory paths, e.g.,
["/some/path", "/another/path", "/yet/another/path", "/still/more"]
and I want to map this list into a list of fully-qualified contents of each of these paths (without . and ..), like this:
["/some/path/file.1", "/some/path/somedir", "/some/path/file.2", "/another/path/file.a", "/another/path/a/directory", "/another/path/file.b", "/still/more/file.alpha", ...]
I figure I could do this with some kind of double-map, like this:
pathItems <- mapM (\pd -> MapM (\contents -> (pd </>) contents) (getDirectoryContents pd) pathDirs
but this doesn't work. The error I'm getting is this:
program.hs:27:56:
Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: FilePath
In the expression: (pd </>) contents
In the first argument of `mapM', namely
`(\ contents -> (pd ) contents)'
program.hs:27:84:
Couldn't match expected type `[FilePath]'
with actual type `IO [FilePath]'
In the second argument of `mapM', namely
`(getDirectoryContents pathDir)'
In the expression:
mapM
(\ contents -> (pd </>) contents)
(getDirectoryContents pd)
A possible solution (importing System.IO System.Directory System.FilePath Control.Applicative):
concat <$> mapM (\pd -> map (pd </>) <$> getDirectoryContents pd) pathDirs
-- ^ this is to work under IO (..)
-- ^ this is to affect what's under IO [..]
-- ^ this returns IO [[FilePath]]
There might be some way to simplify it further.
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