[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