Reputation: 130
I'm a relative beginner at Haskell, but with plenty of background in Mathematics, algebra in particular, so statements like "A monad is a monoid in the category of endofunctors" are not a problem for me.
Even so, I'm only part of the way to understanding monads in Haskell, and in the course of learning I've found myself writing the following function:
bindMap ::(Monad m) => [a -> m a] -> m a -> m a
bindMap (f:fs) s = bindMap fs (s >>= f)
bindMap _ s = s
This serves my purposes completely, but it seems such an obvious function that I thought that either I should be able to find it or define with some simple combinators or (more likely) that I should be thinking about things in a different way.
I originally wrote it with the type signature
[a -> [a]] -> [a] -> [a]
which may give more of an indication of what I'm after. The idea is to join up a list of functions
a -> [a]
into one big function. I'm using it in a Sudoku solver. If you think there could be more relevant context let me know.
Upvotes: 3
Views: 238
Reputation: 27771
When we find ourselves trying to combine two or more "things" in order to get another "thing" of the same type, often a monoid is lurking nearby.
For pure functions, there is the Endo monoid.
Oddly enough, there doesn't seem to be a standard analogue for Kleisli arrows. It would be something like this:
import Data.Monoid
import Control.Monad
newtype EndoM m a = EndoM { appEndoM :: a -> m a }
instance Monad m => Monoid (EndoM m a) where
mempty = EndoM return
EndoM f `mappend` EndoM g = EndoM (f >=> g)
main :: IO ()
main = putStrLn . show . kleisli $ 5
where
kleisli = appEndoM . mconcat . map EndoM $ [return,Just,const Nothing]
Upvotes: 5
Reputation: 213298
It's also called flip (foldl (>>=))
.
In general, if you are looking for a function like [a] -> b
, you are looking for a fold. To compose objects in the monad you might first reach for (>>=)
. The flip
is there because foldl
takes arguments in the opposite order from what you want.
Upvotes: 10