{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Binder.Unfix
(
type (~>)
, Functor1(..)
, Strong1(..)
, Either2(..)
, Var(..)
, Assigned(..)
, PFunctor1
, Mu(..)
, cata1
, MMu
, pcata1
, GFunctor1
, GStrong1
) where
import Data.Kind
import Control.Monad (ap, join)
import GHC.Generics
type f ~> g = forall a. f a -> g a
class
(forall f. Functor f => Functor (h f))
=> Functor1 (h :: (* -> *) -> * -> *)
where
fmap1 :: (Functor f, Functor g) => (f ~> g) -> h f ~> h g
default fmap1
:: ( Generic1 (h f), Generic1 (h g), GFunctor1 (Rep1 (h f)) (Rep1 (h g)) f g
, Functor f, Functor g )
=> (f ~> g) -> h f ~> h g
fmap1 alpha = to1 . gfmap1 alpha . from1
class Functor1 h => Strong1 h where
strength1
:: (Functor f, Applicative g, Functor i)
=> h f (g a) -> (forall b. f (g b) -> i b) -> h i a
default strength1
:: ( Generic1 (h f), Generic1 (h i), GStrong1 (Rep1 (h f)) (Rep1 (h i)) f g i
, Functor f, Applicative g, Functor i )
=> h f (g a) -> (forall b. f (g b) -> i b) -> h i a
strength1 a alpha = to1 $ gstrength1 (from1 a) alpha
data Either2
(h :: (* -> *) -> * -> *) (j :: (* -> *) -> * -> *) (f :: * -> *) (a :: *)
= Left2 (h f a)
| Right2 (j f a)
deriving (Generic1, Functor, Eq)
instance (Functor1 h, Functor1 j) => Functor1 (Either2 h j)
instance (Strong1 h, Strong1 j) => Strong1 (Either2 h j) where
data Var (f :: * -> *) (a :: *) = Var a
deriving (Generic1, Functor, Eq)
instance Functor1 Var where
newtype Assigned (r :: *) (v :: *) (a :: *) = Assigned ((a -> v) -> r)
instance Functor (Assigned r v) where
fmap f (Assigned from) = Assigned $ \assignment -> from (assignment . f)
class
(forall f p. (forall q. Functor (f q)) => Functor (h f p))
=> PFunctor1 (h :: (k -> * -> *) -> k -> * -> *)
where
pfmap1
:: (forall p. Functor (f p), forall q. Functor (g q))
=> (forall q. f q ~> g q) -> h f p ~> h g p
newtype Mu (h :: (* -> *) -> * -> *) (a :: *) = Roll { unroll :: h (Mu h) a }
deriving instance (Eq a, forall b f. (Eq b, forall c. Eq c => Eq (f c)) => Eq (h f b)) => Eq (Mu h a)
instance Functor1 h => Functor (Mu h) where
fmap f (Roll t) = Roll $ fmap f t
instance Strong1 h => Applicative (Mu (Var `Either2` h)) where
pure x = Roll . Left2 $ Var x
(<*>) = ap
instance Strong1 h => Monad (Mu (Var `Either2` h)) where
t >>= subst = joinTerm $ fmap subst t
where
joinTerm
:: Strong1 h
=> Mu (Var `Either2` h) (Mu (Var `Either2` h) a)
-> Mu (Var `Either2` h) a
joinTerm (Roll (Left2 (Var v))) = v
joinTerm (Roll (Right2 u)) = Roll . Right2 $ strength1 u join
cata1 :: (Functor1 h, Functor f) => (h f ~> f) -> Mu h ~> f
cata1 alg (Roll t) = alg $ fmap1 (cata1 alg) t
newtype MMu (h :: (k -> * -> *) -> k -> * -> *) (p :: k) (a :: *)
= MRoll {unmroll :: h (MMu h) p a }
instance PFunctor1 h => Functor (MMu h p) where
fmap f (MRoll t) = MRoll $ fmap f t
pcata1
:: (PFunctor1 h, forall q. Functor (f q))
=> (forall q. h f q ~> f q) -> MMu h p ~> f p
pcata1 alg (MRoll t) = alg $ pfmap1 (pcata1 alg) t
class GFunctor1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *) where
gfmap1 :: (f ~> g) -> (h ~> j)
instance {-# INCOHERENT #-} GFunctor1 (Rec1 f) (Rec1 g) f g where
gfmap1 alpha (Rec1 a) = Rec1 $ alpha a
instance {-# INCOHERENT #-} GFunctor1 (Rec1 i) (Rec1 i) f g where
gfmap1 _ = id
instance {-# INCOHERENT #-} (Functor1 h, Functor f, Functor g)
=> GFunctor1 (Rec1 (h f)) (Rec1 (h g)) f g
where
gfmap1 alpha (Rec1 a) = Rec1 $ fmap1 alpha a
instance GFunctor1 V1 V1 f g where
gfmap1 _ = id
instance GFunctor1 U1 U1 f g where
gfmap1 _ = id
instance GFunctor1 Par1 Par1 f g where
gfmap1 _ = id
instance GFunctor1 (K1 i c) (K1 i c) g f where
gfmap1 _ = id
instance GFunctor1 h j f g => GFunctor1 (M1 i c h) (M1 i c j) f g where
gfmap1 alpha (M1 a) = M1 $ gfmap1 alpha a
instance
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g)
=> GFunctor1 (h1 :+: h2) (j1 :+: j2) f g
where
gfmap1 alpha (L1 a) = L1 $ gfmap1 alpha a
gfmap1 alpha (R1 a) = R1 $ gfmap1 alpha a
instance
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g)
=> GFunctor1 (h1 :*: h2) (j1 :*: j2) f g
where
gfmap1 alpha (a :*: b) = gfmap1 alpha a :*: gfmap1 alpha b
instance
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g, Functor h1)
=> GFunctor1 (h1 :.: h2) (j1 :.: j2) f g
where
gfmap1 alpha (Comp1 a) = Comp1 $ gfmap1 alpha (fmap (gfmap1 alpha) a)
instance {-# INCOHERENT #-} GFunctor1 f g f g where
gfmap1 alpha a = alpha a
class GStrong1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *) (i :: * -> *) where
gstrength1 :: h (g a) -> (forall b. f (g b) -> i b) -> j a
instance {-# INCOHERENT #-} (Strong1 h, Functor f, Applicative g, Functor i)
=> GStrong1 (Rec1 (h f)) (Rec1 (h i)) f g i
where
gstrength1 (Rec1 a) alpha = Rec1 $ strength1 a alpha
instance {-# INCOHERENT #-} GStrong1 (Rec1 f) (Rec1 i) f g i
where
gstrength1 (Rec1 a) alpha = Rec1 $ alpha a
instance GStrong1 V1 V1 f g i where
gstrength1 v _ = case v of {}
instance GStrong1 U1 U1 f g i where
gstrength1 U1 _ = U1
instance GStrong1 (K1 m c) (K1 m c) g f i where
gstrength1 (K1 c) _ = K1 c
instance GStrong1 h j f g i => GStrong1 (M1 m c h) (M1 m c j) f g i where
gstrength1 (M1 a) alpha = M1 $ gstrength1 a alpha
instance
(GStrong1 h1 j1 f g i, GStrong1 h2 j2 f g i)
=> GStrong1 (h1 :+: h2) (j1 :+: j2) f g i
where
gstrength1 (L1 a) alpha = L1 $ gstrength1 a alpha
gstrength1 (R1 a) alpha = R1 $ gstrength1 a alpha
instance
(GStrong1 h1 j1 f g i, GStrong1 h2 j2 f g i)
=> GStrong1 (h1 :*: h2) (j1 :*: j2) f g i
where
gstrength1 (a :*: b) alpha = gstrength1 a alpha :*: gstrength1 b alpha
instance
(GStrong1 h1 j1 f g i, Traversable t, Functor h1, Traversable t, Applicative g)
=> GStrong1 (h1 :.: t) (j1 :.: t) f g i
where
gstrength1 (Comp1 a) alpha = Comp1 $ gstrength1 (fmap sequenceA a) alpha
instance {-# INCOHERENT #-} GStrong1 f i f g i
where
gstrength1 a alpha = alpha a