[Haskell-beginners] Help! Trapped in the IO Monad!

Alexander Dunlap alexander.dunlap at gmail.com
Wed Jan 28 21:55:09 EST 2009


On Wed, Jan 28, 2009 at 6:14 PM, Erik de Castro Lopo
<mle+cl at mega-nerd.com> wrote:
> Alexander Dunlap wrote:
>
>> It seems like foldM ought to do what you want. Could you post some
>> more details please?
>
> This is a function that I have working in Ocaml which is a little
> more lenient about IO :-).
>
> This is what I have but won't compile:
>
>    fileNames :: ([FilePath] -> FilePath -> FilePath -> [FilePath])
>                  -> [FilePath] -> FilePath -> IO [FilePath]
>    fileNames builder builder_accum topdir = do
>        names <- getDirectoryContents topdir
>        let properNames = filter (`notElem` [".", ".."]) names
>        (dirs, files) <- splitDirFile properNames
>        let accum <- foldl' (\ acc f -> builder acc topdir f) builder_accum files
>        return $ foldM (\ acc d -> fileNames builder accum (topdir </> d)) accum dirs
>
> I get following error on the foldM:
>
>    Couldn't match expected type `[FilePath]'
>           against inferred type `IO [FilePath]'
>      Expected type: IO [FilePath]
>      Inferred type: IO (IO [FilePath])
>
> Thinking about it some more, I can see the problem; accum is an
> "IO [FilePath]" and my builder function requires a "[FilePath]".
>
> Once I get the function working I would like to generalize it to:
>
>    fileNames :: (a -> FilePath -> FilePath -> a) -> a -> FilePath -> IO a
>
> Cheers,
> Erik
> --
> -----------------------------------------------------------------
> Erik de Castro Lopo

Try removing the "return $" on the last line. foldM ... will already
be in the IO monad; return will lift the IO a into the IO monad again,
so you'll have IO (IO a), which you don't want.

Alex


More information about the Beginners mailing list