multirec-0.3: examples/SingleUse.hs
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module SingleUse where
import Generics.MultiRec.Base
import Single
-- * Instantiating the library for Logic
-- ** Index type
data LogicF :: * -> * where
Logic :: LogicF Logic
-- ** Constructors
data Var
instance Constructor Var where conName _ = "Var"
data Impl
instance Constructor Impl where
conName _ = ":->:"
conFixity _ = Infix RightAssociative 2
data Equiv
instance Constructor Equiv where
conName _ = ":<->:"
conFixity _ = Infix RightAssociative 1
data And
instance Constructor And where
conName _ = ":&&:"
conFixity _ = Infix RightAssociative 4
data Or
instance Constructor Or where
conName _ = ":||:"
conFixity _ = Infix RightAssociative 3
data Not
instance Constructor Not where conName _ = "Not"
data T
instance Constructor T where conName _ = "T"
data F
instance Constructor F where conName _ = "F"
-- ** Functor encoding
type instance PF LogicF =
( C Var (K String)
:+: C Impl (I Logic :*: I Logic)
:+: C Equiv (I Logic :*: I Logic)
:+: C And (I Logic :*: I Logic)
:+: C Or (I Logic :*: I Logic)
:+: C Not (I Logic)
:+: C T U
:+: C F U
) :>: Logic
-- ** 'El' instance
instance El LogicF Logic where proof = Logic
-- ** 'Fam' instance
instance Fam LogicF where
from Logic (Var s) = Tag (L (C (K s)))
from Logic (l1 :->: l2) = Tag (R (L (C (I (I0 l1) :*: I (I0 l2)))))
from Logic (l1 :<->: l2) = Tag (R (R (L (C (I (I0 l1) :*: I (I0 l2))))))
from Logic (l1 :&&: l2) = Tag (R (R (R (L (C (I (I0 l1) :*: I (I0 l2)))))))
from Logic (l1 :||: l2) = Tag (R (R (R (R (L (C (I (I0 l1) :*: I (I0 l2))))))))
from Logic (Not l) = Tag (R (R (R (R (R (L (C (I (I0 l)))))))))
from Logic T = Tag (R (R (R (R (R (R (L (C U))))))))
from Logic F = Tag (R (R (R (R (R (R (R (C U))))))))
to Logic (Tag (L (C (K s)))) = Var s
to Logic (Tag (R (L (C (I (I0 l1) :*: I (I0 l2)))))) = l1 :->: l2
to Logic (Tag (R (R (L (C (I (I0 l1) :*: I (I0 l2))))))) = l1 :<->: l2
to Logic (Tag (R (R (R (L (C (I (I0 l1) :*: I (I0 l2)))))))) = l1 :&&: l2
to Logic (Tag (R (R (R (R (L (C (I (I0 l1) :*: I (I0 l2))))))))) = l1 :||: l2
to Logic (Tag (R (R (R (R (R (L (C (I (I0 l)))))))))) = Not l
to Logic (Tag (R (R (R (R (R (R (L (C U))))))))) = T
to Logic (Tag (R (R (R (R (R (R (R (C U))))))))) = F