{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances, EmptyCase #-}
{-# LANGUAGE FlexibleInstances, TemplateHaskell, FlexibleContexts #-}
module AST.Term.Var
( Var(..), _Var
, VarType(..)
, ScopeOf, HasScope(..)
) where
import AST
import AST.Infer
import AST.Unify (Unify, UVarOf)
import Control.DeepSeq (NFData)
import qualified Control.Lens as Lens
import Control.Lens.Operators
import Data.Binary (Binary)
import Data.Kind (Type)
import Data.Proxy (Proxy(..))
import GHC.Generics (Generic)
import Text.PrettyPrint.HughesPJClass (Pretty(..))
import Prelude.Compat
type family ScopeOf (t :: Knot -> Type) :: Knot -> Type
class HasScope m s where
getScope :: m (Tree s (UVarOf m))
class VarType var expr where
varType ::
Unify m (TypeOf expr) =>
Proxy expr -> var -> Tree (ScopeOf expr) (UVarOf m) ->
m (Tree (UVarOf m) (TypeOf expr))
newtype Var v (expr :: Knot -> *) (k :: Knot) = Var v
deriving newtype (Eq, Ord, Binary, NFData)
deriving stock (Show, Generic)
Lens.makePrisms ''Var
makeKTraversableApplyAndBases ''Var
instance Pretty v => Pretty (Var v expr k) where
pPrintPrec lvl p (Var v) = pPrintPrec lvl p v
type instance InferOf (Var v t) = ANode (TypeOf t)
instance
( Unify m (TypeOf expr)
, HasScope m (ScopeOf expr)
, VarType v expr
, Monad m
) =>
Infer m (Var v expr) where
{-# INLINE inferBody #-}
inferBody (Var x) =
getScope >>= varType (Proxy @expr) x <&> MkANode <&> (Var x, )