
I'm glad you liked it! There's an interesting different way of doing the first half of your derivation, using a helper function:
transform t l = FM $ \f -> unFM l (t f)
It transforms the map function passed to foldMap. The transform function has this property:
transform a . transform b = transform (b . a)
flatten and fmap can both be written as transformers:
flatten = transform foldMap fmap g = transform (. g)
Now we can derive: (>>= g) = flatten . fmap g = transform foldMap . transform (. g) = transform ((. g) . foldMap) = transform (\f -> foldMap f . g) = FM $ \f -> unFM m (foldMap f . g) Other examples of transform are: filter p = transform (\f e -> if p e then f e else mempty) (<*> xs) = transform (\f g -> unFM xs (f . g)) Unfortunately I couldn't get this code to type-check, so the library doesn't use transform. Sjoerd On Jun 18, 2009, at 11:28 AM, Sebastian Fischer wrote:
On Jun 18, 2009, at 9:57 AM, Sjoerd Visscher wrote:
I am pleased to announce the first release of Data.FMList, lists represented by their foldMap function: [...] http://hackage.haskell.org/package/fmlist-0.1
cool!
Just for fun: a derivation translating between different formulations of monadic bind.
m >>= g = flatten (fmap g m) = FM $ \f -> unFM (fmap g m) (foldMap f) = FM $ \f -> unFM (FM $ \f' -> unFM m (f' . g)) (foldMap f) = FM $ \f -> (\f' -> unFM m (f' . g)) (foldMap f) = FM $ \f -> unFM m (folfMap f . g) -- your definition = FM $ \f -> unFM m (flip unFM f . g) = FM $ \f -> unFM m (\x -> flip unFM f (g x)) = FM $ \f -> unFM m (\x -> unFM (g x) f) -- like continuation monad
Cheers, Sebastian
-- Underestimating the novelty of the future is a time-honored tradition. (D.G.)
-- Sjoerd Visscher sjoerd@w3future.com