Joseph Cooper
Joseph Cooper

Reputation: 130

Does this monadic Haskell function already exist (or is a simple combination of known functions)?

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

Answers (2)

danidiaz
danidiaz

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

Dietrich Epp
Dietrich Epp

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

Related Questions