Skip to content

Instantly share code, notes, and snippets.

@gallais
Created July 14, 2015 20:09
Show Gist options
  • Save gallais/f20ffe68d9282a2dd7c6 to your computer and use it in GitHub Desktop.
Save gallais/f20ffe68d9282a2dd7c6 to your computer and use it in GitHub Desktop.
Match on the Church-encoded Free Monad
{-# LANGUAGE Rank2Types #-}
module MatchFree where
newtype F f a = F { runF :: forall r. (a -> r) -> (f r -> r) -> r }
pureF :: a -> F f a
pureF a = F $ const . ($ a)
freeF :: Functor f => f (F f a) -> F f a
freeF f = F $ \ pr fr -> fr $ fmap (\ inner -> runF inner pr fr) f
type Open f a = Either a (f (F f a))
type Close f a = F f a
close :: Functor f => Open f a -> Close f a
close = either pureF freeF
open
:: Functor f
=> Close f a
-> Open f a
open f = runF f Left (Right . fmap close)
matchF
:: Functor f
=> (a -> r)
-> (f (F f a) -> r)
-> F f a
-> r
matchF kp kf = either kp kf . open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment