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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeHoles #-} -- OMG! module Main ( main -- :: IO () ) where ------------------------------------------------------------------------------- -- Binary trees data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Eq, Show) instance Monad Tree where return = Leaf Leaf x >>= f = f x Node l r >>= f = Node (l >>= f) (r >>= f) ------------------------------------------------------------------------------- -- Free monads data Free f a = Pure a | Free (f (Free f a)) instance Functor f => Monad (Free f) where return = Pure Pure a >>= f = f a Free f >>= g = Free _ ------------------------------------------------------------------------------- -- Trees through free monads data F a = N a a instance Functor f where fmap f (N a b) = N (f a) (f b) toFree :: Tree a -> Free F a toFree (Leaf a) = Pure a toFree (Node l r) = undefined fromFree :: Free F a -> Tree a fromFree (Pure a) = Leaf a fromFree (Free (N a b)) = undefined ------------------------------------------------------------------------------- -- Codensity transformation newtype Codensity m a = C { runCodensity :: forall r. (a -> m r) -> m r} instance Monad (Codensity m) where return x = C undefined C f >>= g = C undefined -- Monad homomorphisms toCodensity :: Monad m => m a -> Codensity m a toCodensity x = C (x >>=) fromCodensity :: Monad m => Codensity m a -> m a fromCodensity (C f) = f return ------------------------------------------------------------------------------- -- Test driver & Examples main :: IO () main = return () {- *Main> :r [1 of 1] Compiling Main ( holes.hs, interpreted ) holes.hs:29:23: Warning: Found hole `_' with type f (Free f b) Where: `f' is a rigid type variable bound by the instance declaration at holes.hs:26:10 `b' is a rigid type variable bound by the type signature for >>= :: Free f a -> (a -> Free f b) -> Free f b at holes.hs:28:10 Relevant bindings include >>= :: Free f a -> (a -> Free f b) -> Free f b (bound at holes.hs:28:3) f :: f (Free f a) (bound at holes.hs:29:8) g :: a -> Free f b (bound at holes.hs:29:14) In the first argument of `Free', namely `_' In the expression: Free (_) In an equation for `>>=': (Free f) >>= g = Free (_) Ok, modules loaded: Main. *Main> -} |