hypertypes-0.2.2: src/Hyper/Syntax/Let.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
module Hyper.Syntax.Let
( Let (..)
, letVar
, letEquals
, letIn
, W_Let (..)
, MorphWitness (..)
) where
import Generics.Constraints (Constraints)
import Hyper
import Hyper.Class.Unify (UVarOf, UnifyGen)
import Hyper.Infer
import Hyper.Unify.Generalize (GTerm, generalize)
import Text.PrettyPrint (($+$), (<+>))
import qualified Text.PrettyPrint as Pretty
import Text.PrettyPrint.HughesPJClass (Pretty (..), maybeParens)
import Hyper.Internal.Prelude
-- | A term for let-expressions with let-generalization.
--
-- @Let v expr@s express let-expressions with @v@s as variable names and @expr@s for terms.
--
-- Apart from the data type, an 'Infer' instance is also provided.
data Let v expr h = Let
{ _letVar :: v
, _letEquals :: h :# expr
, _letIn :: h :# expr
}
deriving (Generic)
makeLenses ''Let
makeCommonInstances [''Let]
makeHTraversableApplyAndBases ''Let
makeZipMatch ''Let
makeHContext ''Let
makeHMorph ''Let
instance
Constraints (Let v expr h) Pretty =>
Pretty (Let v expr h)
where
pPrintPrec lvl p (Let v e i) =
Pretty.text "let"
<+> pPrintPrec lvl 0 v
<+> Pretty.text "="
<+> pPrintPrec lvl 0 e
$+$ pPrintPrec lvl 0 i
& maybeParens (p > 0)
type instance InferOf (Let _ e) = InferOf e
instance
( MonadScopeLevel m
, LocalScopeType v (GTerm (UVarOf m) # TypeOf expr) m
, UnifyGen m (TypeOf expr)
, HasInferredType expr
, HNodesConstraint (InferOf expr) (UnifyGen m)
, HTraversable (InferOf expr)
, Infer m expr
) =>
Infer m (Let v expr)
where
inferBody (Let v e i) =
do
(eI, eG) <-
do
InferredChild eI eR <- inferChild e
generalize (eR ^# inferredType (Proxy @expr))
<&> (eI,)
& localLevel
inferChild i
& localScopeType v eG
<&> \(InferredChild iI iR) -> (Let v eI iI, iR)