HaRe-0.6: refactorer/PwPf/PointlessP/Functors.hs
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
module PointlessP.Functors where
import PointlessP.Combinators
-- Data types as fixed points of functors - PolyP style
class (Functor f) => FunctorOf f d | d -> f
where inn' :: f d -> d
out' :: d -> f d
-- Bridge to data types as explicit fixed points
newtype (Functor f) => Mu f = Mu {unMu :: f (Mu f)}
instance (Functor f) => FunctorOf f (Mu f)
where inn' = Mu
out' = unMu
--infixr 5 :+:
--infixr 6 :*:
--infixr 9 :@:
-- Functors
newtype Id x = Id {unId :: x}
newtype Const t x = Const {unConst :: t}
data (PSum g h) x = Inl (g x) | Inr (h x)
data (PProd g h) x = PProd (g x) (h x)
newtype (PApp g h) x = Comp {unComp :: g (h x)}
-- Maps
instance Functor Id
where fmap f (Id x) = Id (f x)
instance Functor (Const t)
where fmap f (Const x) = Const x
instance (Functor g, Functor h) => Functor (PSum g h)
where fmap f (Inl x) = Inl (fmap f x)
fmap f (Inr x) = Inr (fmap f x)
instance (Functor g, Functor h) => Functor (PProd g h)
where fmap f (PProd x y) = PProd (fmap f x) (fmap f y)
instance (Functor g, Functor h) => Functor (PApp g h)
where fmap f (Comp x) = Comp (fmap (fmap f) x)
-- From functors to sums of products
class Rep a b | a -> b
where to :: a -> b
from :: b -> a
instance Rep (Id x) x
where to (Id x) = x
from x = Id x
instance Rep (Const t x) t
where to (Const t) = t
from t = Const t
instance (Rep (g x) y, Rep (h x) z) => Rep ((PSum g h) x) (Either y z)
where to (Inl a) = Left (to a)
to (Inr a) = Right (to a)
from (Left a) = Inl (from a)
from (Right a) = Inr (from a)
instance (Rep (g x) y, Rep (h x) z) => Rep ((PProd g h) x) (y, z)
where to (PProd a b) = (to a, to b)
from (a, b) = PProd (from a) (from b)
instance (Functor g, Rep (h x) y, Rep (g y) z) => Rep ((PApp g h) x) z
where to (Comp x) = to (fmap to x)
from y = Comp (fmap from (from y))
-- We also need the (obvious) representation of type functors
instance Rep [a] [a]
where to = id
from = id
-- The out and inn functions
out :: (FunctorOf f d, Rep (f d) fd) => d -> fd
out = to . out'
inn :: (FunctorOf f d, Rep (f d) fd) => fd -> d
inn = inn' . from
ouT :: (FunctorOf f d, Rep (f d) fd) => d -> d -> fd
ouT _ = to . out'
inN :: (FunctorOf f d, Rep (f d) fd) => d -> fd -> d
inN _ = inn' . from
-- Auxiliary definitions
instance FunctorOf (PSum (Const One) (PProd (Const a) Id)) [a]
where inn' (Inl (Const _)) = []
inn' (Inr (PProd (Const x) (Id xs))) = x:xs
out' [] = Inl (Const _L)
out' (x:xs) = Inr (PProd (Const x) (Id xs))
nil :: One -> [a]
nil = inn . inl
cons :: (a,[a]) -> [a]
cons = inn . inr
instance FunctorOf (PSum (Const One) Id) Int
where inn' (Inl (Const _)) = 0
inn' (Inr (Id n)) = n+1
out' 0 = Inl (Const _L)
out' (n+1) = Inr (Id n)
zero :: One -> Int
zero = inn . inl
suck :: Int -> Int
suck = inn . inr
instance FunctorOf (PSum (Const One) (Const One)) Bool
where inn' (Inl _) = True
inn' (Inr _) = False
out' True = Inl _L
out' False = Inr _L
true :: One -> Bool
true = inn . inl
false :: One -> Bool
false = inn . inr
fix :: (a->a) -> a
fix f = f (fix f)