[Haskell-beginners] yet another monad question

Chaddaï Fouché chaddai.fouche at gmail.com
Sat Feb 4 14:02:43 CET 2012


On Sat, Feb 4, 2012 at 12:05 PM, David McBride <toad3k at gmail.com> wrote:
> When you pass an argument to
> readDir = findRegularFiles >>= readFiles
>
> it expands to
> readDir arg = (findRegularFiles >>= readFiles) arg
>
> which fails because that expression takes no argument, only
> findRegularFiles does.  Honestly I can't think of any way to get that
> argument in there without explicitly naming it.

I would say the problem is even before that, the expression
"findRegularFiles >>= readFiles" is not well typed :

(>>=) :: Monad m => m a -> (a -> m b) -> m b
specialized here in :
(>>=) :: IO a -> (a -> IO b) -> IO b

but :

findRegularFiles :: FilePath -> IO [FilePath]

so findRegularFiles is not of type "IO a", so can't be the first
argument of (>>=) (or the second of (=<<) since that's just the
flipped version).

But there is a solution ! What you're searching here is a function of type :
? :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)

A kind of monadic composition, there is an operator for that in
Control.Monad since ghc 6.12 or even before :

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)

so :

> readDir = findRegularFiles >=> readFiles

or

> readDir = readFiles <=< findRegularFiles

will work :)

-- 
Jedaï



More information about the Beginners mailing list