public
Last active

If you have a Functor f with an instance Monoid a => Monoid (f a), f is Applicative!

  • Download Gist
liftedMonoid.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
{-# LANGUAGE TypeOperators, ScopedTypeVariables, TupleSections #-}
 
import Data.Constraint
import Data.Monoid
import Control.Applicative
 
 
pureDefault :: forall f a. Functor f
=> (Monoid () :- Monoid (f ()))
-> a -> f a
pureDefault (Sub Dict) a = a <$ (mempty :: f ())
 
apDefault :: forall f a b. Functor f
=> (Monoid (First (a -> b), First a) :- Monoid (f (First (a -> b), First a)))
-> f (a -> b) -> f a -> f b
apDefault (Sub Dict) fab fa = fmap (\(First (Just f), First (Just a)) -> f a) $
fmap (\f -> (First (Just f), mempty)) fab `mappend` fmap (\a -> (mempty, First (Just a))) fa
 
 
-- Example (Dual is just the identity applicative)
 
pfDual :: Monoid a :- Monoid (Dual a)
pfDual = Sub Dict
 
instance Functor Dual where
fmap f (Dual a) = Dual (f a)
 
instance Applicative Dual where
pure = pureDefault pfDual
(<*>) = apDefault pfDual

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.