{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-incomplete-patterns #-}
module Symantic.Reify where
import Control.Monad (Monad(..))
import qualified Data.Function as Fun
import qualified Language.Haskell.TH as TH
import Symantic.Lang (Abstractable(..))
data ReifyReflect repr meta a = ReifyReflect
{
ReifyReflect repr meta a -> meta -> repr a
reify :: meta -> repr a
, ReifyReflect repr meta a -> repr a -> meta
reflect :: repr a -> meta
}
base :: ReifyReflect repr (repr a) a
base :: ReifyReflect repr (repr a) a
base = ReifyReflect :: forall (repr :: * -> *) meta a.
(meta -> repr a) -> (repr a -> meta) -> ReifyReflect repr meta a
ReifyReflect{reify :: repr a -> repr a
reify = repr a -> repr a
forall a. a -> a
Fun.id, reflect :: repr a -> repr a
reflect = repr a -> repr a
forall a. a -> a
Fun.id}
infixr 8 -->
(-->) :: Abstractable repr =>
ReifyReflect repr m1 o1 -> ReifyReflect repr m2 o2 ->
ReifyReflect repr (m1 -> m2) (o1 -> o2)
ReifyReflect repr m1 o1
r1 --> :: ReifyReflect repr m1 o1
-> ReifyReflect repr m2 o2
-> ReifyReflect repr (m1 -> m2) (o1 -> o2)
--> ReifyReflect repr m2 o2
r2 = ReifyReflect :: forall (repr :: * -> *) meta a.
(meta -> repr a) -> (repr a -> meta) -> ReifyReflect repr meta a
ReifyReflect
{ reify :: (m1 -> m2) -> repr (o1 -> o2)
reify = \m1 -> m2
meta -> (repr o1 -> repr o2) -> repr (o1 -> o2)
forall (repr :: * -> *) a b.
Abstractable repr =>
(repr a -> repr b) -> repr (a -> b)
lam (ReifyReflect repr m2 o2 -> m2 -> repr o2
forall (repr :: * -> *) meta a.
ReifyReflect repr meta a -> meta -> repr a
reify ReifyReflect repr m2 o2
r2 (m2 -> repr o2) -> (repr o1 -> m2) -> repr o1 -> repr o2
forall b c a. (b -> c) -> (a -> b) -> a -> c
Fun.. m1 -> m2
meta (m1 -> m2) -> (repr o1 -> m1) -> repr o1 -> m2
forall b c a. (b -> c) -> (a -> b) -> a -> c
Fun.. ReifyReflect repr m1 o1 -> repr o1 -> m1
forall (repr :: * -> *) meta a.
ReifyReflect repr meta a -> repr a -> meta
reflect ReifyReflect repr m1 o1
r1)
, reflect :: repr (o1 -> o2) -> m1 -> m2
reflect = \repr (o1 -> o2)
repr -> ReifyReflect repr m2 o2 -> repr o2 -> m2
forall (repr :: * -> *) meta a.
ReifyReflect repr meta a -> repr a -> meta
reflect ReifyReflect repr m2 o2
r2 (repr o2 -> m2) -> (m1 -> repr o2) -> m1 -> m2
forall b c a. (b -> c) -> (a -> b) -> a -> c
Fun.. repr (o1 -> o2) -> repr o1 -> repr o2
forall (repr :: * -> *) a b.
Abstractable repr =>
repr (a -> b) -> repr a -> repr b
(.@) repr (o1 -> o2)
repr (repr o1 -> repr o2) -> (m1 -> repr o1) -> m1 -> repr o2
forall b c a. (b -> c) -> (a -> b) -> a -> c
Fun.. ReifyReflect repr m1 o1 -> m1 -> repr o1
forall (repr :: * -> *) meta a.
ReifyReflect repr meta a -> meta -> repr a
reify ReifyReflect repr m1 o1
r1
}
reifyTH :: TH.Name -> TH.Q TH.Exp
reifyTH :: Name -> Q Exp
reifyTH Name
name = do
Info
info <- Name -> Q Info
TH.reify Name
name
case Info
info of
TH.VarI Name
n (TH.ForallT [TyVarBndr]
_vs Cxt
_ctx Type
ty) Maybe Dec
_dec ->
[| reify $(genReifyReflect ty) $(return (TH.VarE n)) |]
where
genReifyReflect :: Type -> Q Exp
genReifyReflect (TH.AppT (TH.AppT Type
TH.ArrowT Type
a) Type
b) = [| $(genReifyReflect a) --> $(genReifyReflect b) |]
genReifyReflect TH.VarT{} = [| base |]