{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module PlutusIR.Compiler.Datatype
( compileDatatype
, compileDatatypeDefs
, compileRecDatatypes
, funTyArgs
, funResultType
, mkDatatypeValueType
, mkDestructorTy
, replaceFunTyTarget
, resultTypeName
) where
import PlutusPrelude (showText)
import PlutusIR
import PlutusIR.Compiler.Names
import PlutusIR.Compiler.Provenance
import PlutusIR.Compiler.Types
import PlutusIR.Error
import PlutusIR.MkPir qualified as PIR
import PlutusIR.Transform.Substitute
import PlutusCore.MkPlc qualified as PLC
import PlutusCore.Quote
import PlutusCore.StdLib.Type qualified as Types
import Control.Monad.Error.Lens
import Data.Text qualified as T
import Data.Traversable
import Data.List.NonEmpty qualified as NE
replaceFunTyTarget :: Type tyname uni a -> Type tyname uni a -> Type tyname uni a
replaceFunTyTarget :: Type tyname uni a -> Type tyname uni a -> Type tyname uni a
replaceFunTyTarget Type tyname uni a
newTarget Type tyname uni a
t = case Type tyname uni a
t of
TyFun a
a Type tyname uni a
t1 Type tyname uni a
t2 -> a -> Type tyname uni a -> Type tyname uni a -> Type tyname uni a
forall tyname (uni :: * -> *) ann.
ann
-> Type tyname uni ann
-> Type tyname uni ann
-> Type tyname uni ann
TyFun a
a Type tyname uni a
t1 (Type tyname uni a -> Type tyname uni a)
-> Type tyname uni a -> Type tyname uni a
forall a b. (a -> b) -> a -> b
$ Type tyname uni a -> Type tyname uni a -> Type tyname uni a
forall tyname (uni :: * -> *) a.
Type tyname uni a -> Type tyname uni a -> Type tyname uni a
replaceFunTyTarget Type tyname uni a
newTarget Type tyname uni a
t2
Type tyname uni a
_ -> Type tyname uni a
newTarget
constructorCaseType :: Type tyname uni a -> VarDecl tyname name uni fun a -> Type tyname uni a
constructorCaseType :: Type tyname uni a
-> VarDecl tyname name uni fun a -> Type tyname uni a
constructorCaseType Type tyname uni a
resultType = Type tyname uni a -> Type tyname uni a -> Type tyname uni a
forall tyname (uni :: * -> *) a.
Type tyname uni a -> Type tyname uni a -> Type tyname uni a
replaceFunTyTarget Type tyname uni a
resultType (Type tyname uni a -> Type tyname uni a)
-> (VarDecl tyname name uni fun a -> Type tyname uni a)
-> VarDecl tyname name uni fun a
-> Type tyname uni a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VarDecl tyname name uni fun a -> Type tyname uni a
forall tyname name (uni :: * -> *) k (fun :: k) ann.
VarDecl tyname name uni fun ann -> Type tyname uni ann
_varDeclType
funTySections :: Type tyname uni a -> NE.NonEmpty (Type tyname uni a)
funTySections :: Type tyname uni a -> NonEmpty (Type tyname uni a)
funTySections = \case
TyFun a
_ Type tyname uni a
t1 Type tyname uni a
t2 -> Type tyname uni a
t1 Type tyname uni a
-> NonEmpty (Type tyname uni a) -> NonEmpty (Type tyname uni a)
forall a. a -> NonEmpty a -> NonEmpty a
NE.<| Type tyname uni a -> NonEmpty (Type tyname uni a)
forall tyname (uni :: * -> *) a.
Type tyname uni a -> NonEmpty (Type tyname uni a)
funTySections Type tyname uni a
t2
Type tyname uni a
t -> Type tyname uni a -> NonEmpty (Type tyname uni a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Type tyname uni a
t
funTyArgs :: Type tyname uni a -> [Type tyname uni a]
funTyArgs :: Type tyname uni a -> [Type tyname uni a]
funTyArgs = NonEmpty (Type tyname uni a) -> [Type tyname uni a]
forall a. NonEmpty a -> [a]
NE.init (NonEmpty (Type tyname uni a) -> [Type tyname uni a])
-> (Type tyname uni a -> NonEmpty (Type tyname uni a))
-> Type tyname uni a
-> [Type tyname uni a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type tyname uni a -> NonEmpty (Type tyname uni a)
forall tyname (uni :: * -> *) a.
Type tyname uni a -> NonEmpty (Type tyname uni a)
funTySections
funResultType :: Type tyname uni a -> Type tyname uni a
funResultType :: Type tyname uni a -> Type tyname uni a
funResultType = NonEmpty (Type tyname uni a) -> Type tyname uni a
forall a. NonEmpty a -> a
NE.last (NonEmpty (Type tyname uni a) -> Type tyname uni a)
-> (Type tyname uni a -> NonEmpty (Type tyname uni a))
-> Type tyname uni a
-> Type tyname uni a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type tyname uni a -> NonEmpty (Type tyname uni a)
forall tyname (uni :: * -> *) a.
Type tyname uni a -> NonEmpty (Type tyname uni a)
funTySections
constructorArgTypes :: VarDecl tyname name uni fun a -> [Type tyname uni a]
constructorArgTypes :: VarDecl tyname name uni fun a -> [Type tyname uni a]
constructorArgTypes = Type tyname uni a -> [Type tyname uni a]
forall tyname (uni :: * -> *) a.
Type tyname uni a -> [Type tyname uni a]
funTyArgs (Type tyname uni a -> [Type tyname uni a])
-> (VarDecl tyname name uni fun a -> Type tyname uni a)
-> VarDecl tyname name uni fun a
-> [Type tyname uni a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VarDecl tyname name uni fun a -> Type tyname uni a
forall tyname name (uni :: * -> *) k (fun :: k) ann.
VarDecl tyname name uni fun ann -> Type tyname uni ann
_varDeclType
unveilDatatype :: Eq tyname => Type tyname uni a -> Datatype tyname name uni fun a -> Type tyname uni a -> Type tyname uni a
unveilDatatype :: Type tyname uni a
-> Datatype tyname name uni fun a
-> Type tyname uni a
-> Type tyname uni a
unveilDatatype Type tyname uni a
dty (Datatype a
_ TyVarDecl tyname a
tn [TyVarDecl tyname a]
_ name
_ [VarDecl tyname name uni fun a]
_) = (tyname -> Maybe (Type tyname uni a))
-> Type tyname uni a -> Type tyname uni a
forall tyname (uni :: * -> *) ann.
(tyname -> Maybe (Type tyname uni ann))
-> Type tyname uni ann -> Type tyname uni ann
typeSubstTyNames (\tyname
n -> if tyname
n tyname -> tyname -> Bool
forall a. Eq a => a -> a -> Bool
== TyVarDecl tyname a -> tyname
forall tyname ann. TyVarDecl tyname ann -> tyname
_tyVarDeclName TyVarDecl tyname a
tn then Type tyname uni a -> Maybe (Type tyname uni a)
forall a. a -> Maybe a
Just Type tyname uni a
dty else Maybe (Type tyname uni a)
forall a. Maybe a
Nothing)
resultTypeName :: MonadQuote m => Datatype TyName Name uni fun a -> m TyName
resultTypeName :: Datatype TyName Name uni fun a -> m TyName
resultTypeName (Datatype a
_ TyVarDecl TyName a
tn [TyVarDecl TyName a]
_ Name
_ [VarDecl TyName Name uni fun a]
_) = Quote TyName -> m TyName
forall (m :: * -> *) a. MonadQuote m => Quote a -> m a
liftQuote (Quote TyName -> m TyName) -> Quote TyName -> m TyName
forall a b. (a -> b) -> a -> b
$ Text -> Quote TyName
forall (m :: * -> *). MonadQuote m => Text -> m TyName
freshTyName (Text -> Quote TyName) -> Text -> Quote TyName
forall a b. (a -> b) -> a -> b
$ Text
"out_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Name -> Text
nameString (Name -> Text) -> Name -> Text
forall a b. (a -> b) -> a -> b
$ TyName -> Name
unTyName (TyName -> Name) -> TyName -> Name
forall a b. (a -> b) -> a -> b
$ TyVarDecl TyName a -> TyName
forall tyname ann. TyVarDecl tyname ann -> tyname
_tyVarDeclName TyVarDecl TyName a
tn)
mkScottTy :: MonadQuote m => ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkScottTy :: ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkScottTy ann
ann d :: Datatype TyName Name uni fun ann
d@(Datatype ann
_ TyVarDecl TyName ann
_ [TyVarDecl TyName ann]
_ Name
_ [VarDecl TyName Name uni fun ann]
constrs) = do
TyName
resultType <- Datatype TyName Name uni fun ann -> m TyName
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
Datatype TyName Name uni fun a -> m TyName
resultTypeName Datatype TyName Name uni fun ann
d
let caseTys :: [Type TyName uni ann]
caseTys = (VarDecl TyName Name uni fun ann -> Type TyName uni ann)
-> [VarDecl TyName Name uni fun ann] -> [Type TyName uni ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Type TyName uni ann
-> VarDecl TyName Name uni fun ann -> Type TyName uni ann
forall tyname (uni :: * -> *) a name fun.
Type tyname uni a
-> VarDecl tyname name uni fun a -> Type tyname uni a
constructorCaseType (ann -> TyName -> Type TyName uni ann
forall tyname (uni :: * -> *) ann.
ann -> tyname -> Type tyname uni ann
TyVar ann
ann TyName
resultType)) [VarDecl TyName Name uni fun ann]
constrs
Type TyName uni ann -> m (Type TyName uni ann)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type TyName uni ann -> m (Type TyName uni ann))
-> Type TyName uni ann -> m (Type TyName uni ann)
forall a b. (a -> b) -> a -> b
$
ann
-> TyName -> Kind ann -> Type TyName uni ann -> Type TyName uni ann
forall tyname (uni :: * -> *) ann.
ann
-> tyname -> Kind ann -> Type tyname uni ann -> Type tyname uni ann
TyForall ann
ann TyName
resultType (ann -> Kind ann
forall ann. ann -> Kind ann
Type ann
ann) (Type TyName uni ann -> Type TyName uni ann)
-> Type TyName uni ann -> Type TyName uni ann
forall a b. (a -> b) -> a -> b
$
ann
-> [Type TyName uni ann]
-> Type TyName uni ann
-> Type TyName uni ann
forall ann tyname (uni :: * -> *).
ann
-> [Type tyname uni ann]
-> Type tyname uni ann
-> Type tyname uni ann
PIR.mkIterTyFun ann
ann [Type TyName uni ann]
caseTys (ann -> TyName -> Type TyName uni ann
forall tyname (uni :: * -> *) ann.
ann -> tyname -> Type tyname uni ann
TyVar ann
ann TyName
resultType)
mkDatatypePatternFunctor :: MonadQuote m => ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkDatatypePatternFunctor :: ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkDatatypePatternFunctor ann
ann Datatype TyName Name uni fun ann
d = ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
forall (m :: * -> *) ann (uni :: * -> *) fun.
MonadQuote m =>
ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkScottTy ann
ann Datatype TyName Name uni fun ann
d
mkDatatypeType :: forall m uni fun a. MonadQuote m => Recursivity -> PIRType uni a -> Datatype TyName Name uni fun (Provenance a) -> m (PLCRecType uni fun a)
mkDatatypeType :: Recursivity
-> PIRType uni a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PLCRecType uni fun a)
mkDatatypeType Recursivity
r PIRType uni a
pf (Datatype Provenance a
ann TyVarDecl TyName (Provenance a)
tn [TyVarDecl TyName (Provenance a)]
tvs Name
_ [VarDecl TyName Name uni fun (Provenance a)]
_) = case Recursivity
r of
Recursivity
NonRec -> PIRType uni a -> PLCRecType uni fun a
forall (uni :: * -> *) fun a. PLCType uni a -> PLCRecType uni fun a
PlainType (PIRType uni a -> PLCRecType uni fun a)
-> m (PIRType uni a) -> m (PLCRecType uni fun a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([TyVarDecl TyName (Provenance a)] -> PIRType uni a -> PIRType uni a
forall tyname ann (uni :: * -> *).
[TyVarDecl tyname ann]
-> Type tyname uni ann -> Type tyname uni ann
PLC.mkIterTyLam ([TyVarDecl TyName (Provenance a)]
-> PIRType uni a -> PIRType uni a)
-> m [TyVarDecl TyName (Provenance a)]
-> m (PIRType uni a -> PIRType uni a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVarDecl TyName (Provenance a)]
-> m [TyVarDecl TyName (Provenance a)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TyVarDecl TyName (Provenance a)]
tvs m (PIRType uni a -> PIRType uni a)
-> m (PIRType uni a) -> m (PIRType uni a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> PIRType uni a -> m (PIRType uni a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PIRType uni a
pf)
Recursivity
Rec -> do
RecursiveType uni fun (Provenance a) -> PLCRecType uni fun a
forall (uni :: * -> *) fun a.
RecursiveType uni fun (Provenance a) -> PLCRecType uni fun a
RecursiveType (RecursiveType uni fun (Provenance a) -> PLCRecType uni fun a)
-> m (RecursiveType uni fun (Provenance a))
-> m (PLCRecType uni fun a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Quote (RecursiveType uni fun (Provenance a))
-> m (RecursiveType uni fun (Provenance a))
forall (m :: * -> *) a. MonadQuote m => Quote a -> m a
liftQuote (Quote (RecursiveType uni fun (Provenance a))
-> m (RecursiveType uni fun (Provenance a)))
-> Quote (RecursiveType uni fun (Provenance a))
-> m (RecursiveType uni fun (Provenance a))
forall a b. (a -> b) -> a -> b
$ FromDataPieces
uni (Provenance a) (RecursiveType uni fun (Provenance a))
forall (uni :: * -> *) ann fun.
FromDataPieces uni ann (RecursiveType uni fun ann)
Types.makeRecursiveType @uni @(Provenance a) Provenance a
ann (TyVarDecl TyName (Provenance a) -> TyName
forall tyname ann. TyVarDecl tyname ann -> tyname
_tyVarDeclName TyVarDecl TyName (Provenance a)
tn) [TyVarDecl TyName (Provenance a)]
tvs PIRType uni a
pf)
mkDatatypeValueType :: a -> Datatype TyName Name uni fun a -> Type TyName uni a
mkDatatypeValueType :: a -> Datatype TyName Name uni fun a -> Type TyName uni a
mkDatatypeValueType a
ann (Datatype a
_ TyVarDecl TyName a
tn [TyVarDecl TyName a]
tvs Name
_ [VarDecl TyName Name uni fun a]
_) = a -> Type TyName uni a -> [Type TyName uni a] -> Type TyName uni a
forall ann tyname (uni :: * -> *).
ann
-> Type tyname uni ann
-> [Type tyname uni ann]
-> Type tyname uni ann
PIR.mkIterTyApp a
ann (a -> TyVarDecl TyName a -> Type TyName uni a
forall ann tyname (uni :: * -> *).
ann -> TyVarDecl tyname ann -> Type tyname uni ann
PIR.mkTyVar a
ann TyVarDecl TyName a
tn) ([Type TyName uni a] -> Type TyName uni a)
-> [Type TyName uni a] -> Type TyName uni a
forall a b. (a -> b) -> a -> b
$ a -> TyVarDecl TyName a -> Type TyName uni a
forall ann tyname (uni :: * -> *).
ann -> TyVarDecl tyname ann -> Type tyname uni ann
PIR.mkTyVar a
ann (TyVarDecl TyName a -> Type TyName uni a)
-> [TyVarDecl TyName a] -> [Type TyName uni a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVarDecl TyName a]
tvs
mkConstructorType :: Datatype TyName Name uni fun (Provenance a) -> VarDecl TyName Name uni fun (Provenance a) -> PIRType uni a
mkConstructorType :: Datatype TyName Name uni fun (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a) -> PIRType uni a
mkConstructorType (Datatype Provenance a
_ TyVarDecl TyName (Provenance a)
_ [TyVarDecl TyName (Provenance a)]
tvs Name
_ [VarDecl TyName Name uni fun (Provenance a)]
_) VarDecl TyName Name uni fun (Provenance a)
constr =
let constrTy :: PIRType uni a
constrTy = [TyVarDecl TyName (Provenance a)] -> PIRType uni a -> PIRType uni a
forall tyname ann (uni :: * -> *).
[TyVarDecl tyname ann]
-> Type tyname uni ann -> Type tyname uni ann
PIR.mkIterTyForall [TyVarDecl TyName (Provenance a)]
tvs (PIRType uni a -> PIRType uni a) -> PIRType uni a -> PIRType uni a
forall a b. (a -> b) -> a -> b
$ VarDecl TyName Name uni fun (Provenance a) -> PIRType uni a
forall tyname name (uni :: * -> *) k (fun :: k) ann.
VarDecl tyname name uni fun ann -> Type tyname uni ann
_varDeclType VarDecl TyName Name uni fun (Provenance a)
constr
in (Provenance a -> Provenance a) -> PIRType uni a -> PIRType uni a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Provenance a
a -> DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
ConstructorType Provenance a
a) PIRType uni a
constrTy
mkConstructor :: MonadQuote m => PLCRecType uni fun a -> Datatype TyName Name uni fun (Provenance a) -> Int -> m (PIRTerm uni fun a)
mkConstructor :: PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> Int
-> m (PIRTerm uni fun a)
mkConstructor PLCRecType uni fun a
dty d :: Datatype TyName Name uni fun (Provenance a)
d@(Datatype Provenance a
ann TyVarDecl TyName (Provenance a)
_ [TyVarDecl TyName (Provenance a)]
tvs Name
_ [VarDecl TyName Name uni fun (Provenance a)]
constrs) Int
index = do
TyName
resultType <- Datatype TyName Name uni fun (Provenance a) -> m TyName
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
Datatype TyName Name uni fun a -> m TyName
resultTypeName Datatype TyName Name uni fun (Provenance a)
d
[VarDecl TyName Name uni fun (Provenance a)]
casesAndTypes <- do
let caseTypes :: [Type TyName uni (Provenance a)]
caseTypes = Type TyName uni (Provenance a)
-> Datatype TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a)
-> Type TyName uni (Provenance a)
forall tyname (uni :: * -> *) a name fun.
Eq tyname =>
Type tyname uni a
-> Datatype tyname name uni fun a
-> Type tyname uni a
-> Type tyname uni a
unveilDatatype (PLCRecType uni fun a -> Type TyName uni (Provenance a)
forall (uni :: * -> *) fun a. PLCRecType uni fun a -> PLCType uni a
getType PLCRecType uni fun a
dty) Datatype TyName Name uni fun (Provenance a)
d (Type TyName uni (Provenance a) -> Type TyName uni (Provenance a))
-> [Type TyName uni (Provenance a)]
-> [Type TyName uni (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (VarDecl TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a))
-> [VarDecl TyName Name uni fun (Provenance a)]
-> [Type TyName uni (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a)
forall tyname (uni :: * -> *) a name fun.
Type tyname uni a
-> VarDecl tyname name uni fun a -> Type tyname uni a
constructorCaseType (Provenance a -> TyName -> Type TyName uni (Provenance a)
forall tyname (uni :: * -> *) ann.
ann -> tyname -> Type tyname uni ann
TyVar Provenance a
ann TyName
resultType)) [VarDecl TyName Name uni fun (Provenance a)]
constrs
[Name]
caseArgNames <- [VarDecl TyName Name uni fun (Provenance a)]
-> (VarDecl TyName Name uni fun (Provenance a) -> m Name)
-> m [Name]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [VarDecl TyName Name uni fun (Provenance a)]
constrs (\VarDecl TyName Name uni fun (Provenance a)
c -> Text -> m Name
forall (m :: * -> *). MonadQuote m => Text -> m Name
safeFreshName (Text -> m Name) -> Text -> m Name
forall a b. (a -> b) -> a -> b
$ Text
"case_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (VarDecl TyName Name uni fun (Provenance a) -> String
forall tyname (uni :: * -> *) fun a.
VarDecl tyname Name uni fun a -> String
varDeclNameString VarDecl TyName Name uni fun (Provenance a)
c))
[VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)])
-> [VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)]
forall a b. (a -> b) -> a -> b
$ (Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a))
-> [Name]
-> [Type TyName uni (Provenance a)]
-> [VarDecl TyName Name uni fun (Provenance a)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Provenance a
-> Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
forall k tyname name (uni :: * -> *) (fun :: k) ann.
ann
-> name -> Type tyname uni ann -> VarDecl tyname name uni fun ann
VarDecl Provenance a
ann) [Name]
caseArgNames [Type TyName uni (Provenance a)]
caseTypes
let thisConstr :: VarDecl TyName Name uni fun (Provenance a)
thisConstr = [VarDecl TyName Name uni fun (Provenance a)]
constrs [VarDecl TyName Name uni fun (Provenance a)]
-> Int -> VarDecl TyName Name uni fun (Provenance a)
forall a. [a] -> Int -> a
!! Int
index
let thisCase :: PIRTerm uni fun a
thisCase = Provenance a
-> VarDecl TyName Name uni fun (Provenance a) -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
ann -> VarDecl tyname name uni fun ann -> term ann
PIR.mkVar Provenance a
ann (VarDecl TyName Name uni fun (Provenance a) -> PIRTerm uni fun a)
-> VarDecl TyName Name uni fun (Provenance a) -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$ [VarDecl TyName Name uni fun (Provenance a)]
casesAndTypes [VarDecl TyName Name uni fun (Provenance a)]
-> Int -> VarDecl TyName Name uni fun (Provenance a)
forall a. [a] -> Int -> a
!! Int
index
[VarDecl TyName Name uni fun (Provenance a)]
argsAndTypes <- do
let argTypes :: [Type TyName uni (Provenance a)]
argTypes = Type TyName uni (Provenance a)
-> Datatype TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a)
-> Type TyName uni (Provenance a)
forall tyname (uni :: * -> *) a name fun.
Eq tyname =>
Type tyname uni a
-> Datatype tyname name uni fun a
-> Type tyname uni a
-> Type tyname uni a
unveilDatatype (PLCRecType uni fun a -> Type TyName uni (Provenance a)
forall (uni :: * -> *) fun a. PLCRecType uni fun a -> PLCType uni a
getType PLCRecType uni fun a
dty) Datatype TyName Name uni fun (Provenance a)
d (Type TyName uni (Provenance a) -> Type TyName uni (Provenance a))
-> [Type TyName uni (Provenance a)]
-> [Type TyName uni (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VarDecl TyName Name uni fun (Provenance a)
-> [Type TyName uni (Provenance a)]
forall tyname name (uni :: * -> *) fun a.
VarDecl tyname name uni fun a -> [Type tyname uni a]
constructorArgTypes VarDecl TyName Name uni fun (Provenance a)
thisConstr
[Name]
argNames <- [Int] -> (Int -> m Name) -> m [Name]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [Int
0..([Type TyName uni (Provenance a)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type TyName uni (Provenance a)]
argTypes Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] (\Int
i -> Text -> m Name
forall (m :: * -> *). MonadQuote m => Text -> m Name
safeFreshName (Text -> m Name) -> Text -> m Name
forall a b. (a -> b) -> a -> b
$ Text
"arg_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showText Int
i)
[VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)])
-> [VarDecl TyName Name uni fun (Provenance a)]
-> m [VarDecl TyName Name uni fun (Provenance a)]
forall a b. (a -> b) -> a -> b
$ (Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a))
-> [Name]
-> [Type TyName uni (Provenance a)]
-> [VarDecl TyName Name uni fun (Provenance a)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Provenance a
-> Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
forall k tyname name (uni :: * -> *) (fun :: k) ann.
ann
-> name -> Type tyname uni ann -> VarDecl tyname name uni fun ann
VarDecl Provenance a
ann) [Name]
argNames [Type TyName uni (Provenance a)]
argTypes
let constr :: PIRTerm uni fun a
constr =
[TyVarDecl TyName (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[TyVarDecl tyname ann] -> term ann -> term ann
PIR.mkIterTyAbs [TyVarDecl TyName (Provenance a)]
tvs (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
[VarDecl TyName Name uni fun (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[VarDecl tyname name uni fun ann] -> term ann -> term ann
PIR.mkIterLamAbs [VarDecl TyName Name uni fun (Provenance a)]
argsAndTypes (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a
-> PLCRecType uni fun a
-> [Type TyName uni (Provenance a)]
-> PIRTerm uni fun a
-> PIRTerm uni fun a
forall a (uni :: * -> *) fun.
Provenance a
-> PLCRecType uni fun a
-> [PLCType uni a]
-> PIRTerm uni fun a
-> PIRTerm uni fun a
wrap Provenance a
ann PLCRecType uni fun a
dty ((TyVarDecl TyName (Provenance a) -> Type TyName uni (Provenance a))
-> [TyVarDecl TyName (Provenance a)]
-> [Type TyName uni (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Provenance a
-> TyVarDecl TyName (Provenance a)
-> Type TyName uni (Provenance a)
forall ann tyname (uni :: * -> *).
ann -> TyVarDecl tyname ann -> Type tyname uni ann
PIR.mkTyVar Provenance a
ann) [TyVarDecl TyName (Provenance a)]
tvs)(PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a
-> TyName
-> Kind (Provenance a)
-> PIRTerm uni fun a
-> PIRTerm uni fun a
forall tyname name (uni :: * -> *) fun a.
a
-> tyname
-> Kind a
-> Term tyname name uni fun a
-> Term tyname name uni fun a
TyAbs Provenance a
ann TyName
resultType (Provenance a -> Kind (Provenance a)
forall ann. ann -> Kind ann
Type Provenance a
ann) (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
[VarDecl TyName Name uni fun (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[VarDecl tyname name uni fun ann] -> term ann -> term ann
PIR.mkIterLamAbs [VarDecl TyName Name uni fun (Provenance a)]
casesAndTypes (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a
-> PIRTerm uni fun a -> [PIRTerm uni fun a] -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
ann -> term ann -> [term ann] -> term ann
PIR.mkIterApp Provenance a
ann PIRTerm uni fun a
thisCase ((VarDecl TyName Name uni fun (Provenance a) -> PIRTerm uni fun a)
-> [VarDecl TyName Name uni fun (Provenance a)]
-> [PIRTerm uni fun a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Provenance a
-> VarDecl TyName Name uni fun (Provenance a) -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
ann -> VarDecl tyname name uni fun ann -> term ann
PIR.mkVar Provenance a
ann) [VarDecl TyName Name uni fun (Provenance a)]
argsAndTypes)
PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PIRTerm uni fun a -> m (PIRTerm uni fun a))
-> PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall a b. (a -> b) -> a -> b
$ (Provenance a -> Provenance a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Provenance a
a -> DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
Constructor Provenance a
a) PIRTerm uni fun a
constr
mkDestructor :: MonadQuote m => PLCRecType uni fun a -> Datatype TyName Name uni fun (Provenance a) -> m (PIRTerm uni fun a)
mkDestructor :: PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
mkDestructor PLCRecType uni fun a
dty (Datatype Provenance a
ann TyVarDecl TyName (Provenance a)
_ [TyVarDecl TyName (Provenance a)]
tvs Name
_ [VarDecl TyName Name uni fun (Provenance a)]
_) = do
let appliedReal :: Type TyName uni (Provenance a)
appliedReal = Provenance a
-> Type TyName uni (Provenance a)
-> [Type TyName uni (Provenance a)]
-> Type TyName uni (Provenance a)
forall ann tyname (uni :: * -> *).
ann
-> Type tyname uni ann
-> [Type tyname uni ann]
-> Type tyname uni ann
PIR.mkIterTyApp Provenance a
ann (PLCRecType uni fun a -> Type TyName uni (Provenance a)
forall (uni :: * -> *) fun a. PLCRecType uni fun a -> PLCType uni a
getType PLCRecType uni fun a
dty) ((TyVarDecl TyName (Provenance a) -> Type TyName uni (Provenance a))
-> [TyVarDecl TyName (Provenance a)]
-> [Type TyName uni (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Provenance a
-> TyVarDecl TyName (Provenance a)
-> Type TyName uni (Provenance a)
forall ann tyname (uni :: * -> *).
ann -> TyVarDecl tyname ann -> Type tyname uni ann
PIR.mkTyVar Provenance a
ann) [TyVarDecl TyName (Provenance a)]
tvs)
Name
xn <- Text -> m Name
forall (m :: * -> *). MonadQuote m => Text -> m Name
safeFreshName Text
"x"
let destr :: PIRTerm uni fun a
destr =
[TyVarDecl TyName (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[TyVarDecl tyname ann] -> term ann -> term ann
PIR.mkIterTyAbs [TyVarDecl TyName (Provenance a)]
tvs (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a
-> Name
-> Type TyName uni (Provenance a)
-> PIRTerm uni fun a
-> PIRTerm uni fun a
forall tyname name (uni :: * -> *) fun a.
a
-> name
-> Type tyname uni a
-> Term tyname name uni fun a
-> Term tyname name uni fun a
LamAbs Provenance a
ann Name
xn Type TyName uni (Provenance a)
appliedReal (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a
-> PLCRecType uni fun a -> PIRTerm uni fun a -> PIRTerm uni fun a
forall a (uni :: * -> *) fun.
Provenance a
-> PLCRecType uni fun a -> PIRTerm uni fun a -> PIRTerm uni fun a
unwrap Provenance a
ann PLCRecType uni fun a
dty (PIRTerm uni fun a -> PIRTerm uni fun a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall a b. (a -> b) -> a -> b
$
Provenance a -> Name -> PIRTerm uni fun a
forall tyname name (uni :: * -> *) fun a.
a -> name -> Term tyname name uni fun a
Var Provenance a
ann Name
xn
PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PIRTerm uni fun a -> m (PIRTerm uni fun a))
-> PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall a b. (a -> b) -> a -> b
$ (Provenance a -> Provenance a)
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Provenance a
a -> DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
Destructor Provenance a
a) PIRTerm uni fun a
destr
mkDestructorTy :: PIRType uni a -> Datatype TyName Name uni fun (Provenance a) -> PIRType uni a
mkDestructorTy :: PIRType uni a
-> Datatype TyName Name uni fun (Provenance a) -> PIRType uni a
mkDestructorTy PIRType uni a
pf dt :: Datatype TyName Name uni fun (Provenance a)
dt@(Datatype Provenance a
ann TyVarDecl TyName (Provenance a)
_ [TyVarDecl TyName (Provenance a)]
tvs Name
_ [VarDecl TyName Name uni fun (Provenance a)]
_) =
let appliedAbstract :: PIRType uni a
appliedAbstract = Provenance a
-> Datatype TyName Name uni fun (Provenance a) -> PIRType uni a
forall a (uni :: * -> *) fun.
a -> Datatype TyName Name uni fun a -> Type TyName uni a
mkDatatypeValueType Provenance a
ann Datatype TyName Name uni fun (Provenance a)
dt
destrTy :: PIRType uni a
destrTy = [TyVarDecl TyName (Provenance a)] -> PIRType uni a -> PIRType uni a
forall tyname ann (uni :: * -> *).
[TyVarDecl tyname ann]
-> Type tyname uni ann -> Type tyname uni ann
PIR.mkIterTyForall [TyVarDecl TyName (Provenance a)]
tvs (PIRType uni a -> PIRType uni a) -> PIRType uni a -> PIRType uni a
forall a b. (a -> b) -> a -> b
$ Provenance a -> PIRType uni a -> PIRType uni a -> PIRType uni a
forall tyname (uni :: * -> *) ann.
ann
-> Type tyname uni ann
-> Type tyname uni ann
-> Type tyname uni ann
TyFun Provenance a
ann PIRType uni a
appliedAbstract PIRType uni a
pf
in (Provenance a -> Provenance a) -> PIRType uni a -> PIRType uni a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Provenance a
a -> DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
DestructorType Provenance a
a) PIRType uni a
destrTy
compileDatatype :: Compiling m e uni fun a => Recursivity -> PIRTerm uni fun a -> Datatype TyName Name uni fun (Provenance a) -> m (PIRTerm uni fun a)
compileDatatype :: Recursivity
-> PIRTerm uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
compileDatatype Recursivity
r PIRTerm uni fun a
body Datatype TyName Name uni fun (Provenance a)
d = do
Provenance a
p <- m (Provenance a)
forall (uni :: * -> *) fun a (m :: * -> *).
MonadReader (CompilationCtx uni fun a) m =>
m (Provenance a)
getEnclosing
(Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef, [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
constrDefs, Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
destrDef) <- Recursivity
-> Datatype TyName Name uni fun (Provenance a)
-> m (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
Recursivity
-> Datatype TyName Name uni fun (Provenance a)
-> m (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
compileDatatypeDefs Recursivity
r Datatype TyName Name uni fun (Provenance a)
d
let
tyVars :: [TyVarDecl TyName (Provenance a)]
tyVars = [Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
-> TyVarDecl TyName (Provenance a)
forall var val. Def var val -> var
PIR.defVar Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef]
tys :: [PLCType uni a]
tys = [PLCRecType uni fun a -> PLCType uni a
forall (uni :: * -> *) fun a. PLCRecType uni fun a -> PLCType uni a
getType (PLCRecType uni fun a -> PLCType uni a)
-> PLCRecType uni fun a -> PLCType uni a
forall a b. (a -> b) -> a -> b
$ Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
-> PLCRecType uni fun a
forall var val. Def var val -> val
PIR.defVal Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef]
vars :: [VarDecl TyName Name uni fun (Provenance a)]
vars = (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> VarDecl TyName Name uni fun (Provenance a))
-> [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
-> [VarDecl TyName Name uni fun (Provenance a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> VarDecl TyName Name uni fun (Provenance a)
forall var val. Def var val -> var
PIR.defVar [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
constrDefs [VarDecl TyName Name uni fun (Provenance a)]
-> [VarDecl TyName Name uni fun (Provenance a)]
-> [VarDecl TyName Name uni fun (Provenance a)]
forall a. [a] -> [a] -> [a]
++ [ Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> VarDecl TyName Name uni fun (Provenance a)
forall var val. Def var val -> var
PIR.defVar Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
destrDef ]
vals :: [PIRTerm uni fun a]
vals = (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> PIRTerm uni fun a)
-> [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
-> [PIRTerm uni fun a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> PIRTerm uni fun a
forall var val. Def var val -> val
PIR.defVal [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
constrDefs [PIRTerm uni fun a] -> [PIRTerm uni fun a] -> [PIRTerm uni fun a]
forall a. [a] -> [a] -> [a]
++ [ Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
-> PIRTerm uni fun a
forall var val. Def var val -> val
PIR.defVal Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
destrDef ]
PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PIRTerm uni fun a -> m (PIRTerm uni fun a))
-> PIRTerm uni fun a -> m (PIRTerm uni fun a)
forall a b. (a -> b) -> a -> b
$ Provenance a
-> PIRTerm uni fun a -> [PIRTerm uni fun a] -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
ann -> term ann -> [term ann] -> term ann
PIR.mkIterApp Provenance a
p (Provenance a
-> PIRTerm uni fun a -> [PLCType uni a] -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
ann -> term ann -> [Type tyname uni ann] -> term ann
PIR.mkIterInst Provenance a
p ([TyVarDecl TyName (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[TyVarDecl tyname ann] -> term ann -> term ann
PIR.mkIterTyAbs [TyVarDecl TyName (Provenance a)]
tyVars ([VarDecl TyName Name uni fun (Provenance a)]
-> PIRTerm uni fun a -> PIRTerm uni fun a
forall (term :: * -> *) tyname name (uni :: * -> *) fun ann.
TermLike term tyname name uni fun =>
[VarDecl tyname name uni fun ann] -> term ann -> term ann
PIR.mkIterLamAbs [VarDecl TyName Name uni fun (Provenance a)]
vars PIRTerm uni fun a
body)) [PLCType uni a]
tys) [PIRTerm uni fun a]
vals
compileDatatypeDefs :: MonadQuote m => Recursivity
-> Datatype TyName Name uni fun (Provenance a)
-> m (PLC.Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[PLC.Def (VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
PLC.Def (VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
compileDatatypeDefs :: Recursivity
-> Datatype TyName Name uni fun (Provenance a)
-> m (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
compileDatatypeDefs Recursivity
r d :: Datatype TyName Name uni fun (Provenance a)
d@(Datatype Provenance a
ann TyVarDecl TyName (Provenance a)
tn [TyVarDecl TyName (Provenance a)]
_ Name
destr [VarDecl TyName Name uni fun (Provenance a)]
constrs) = do
Type TyName uni (Provenance a)
pf <- Provenance a
-> Datatype TyName Name uni fun (Provenance a)
-> m (Type TyName uni (Provenance a))
forall (m :: * -> *) ann (uni :: * -> *) fun.
MonadQuote m =>
ann -> Datatype TyName Name uni fun ann -> m (Type TyName uni ann)
mkDatatypePatternFunctor Provenance a
ann Datatype TyName Name uni fun (Provenance a)
d
Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef <- TyVarDecl TyName (Provenance a)
-> PLCRecType uni fun a
-> Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
forall var val. var -> val -> Def var val
PIR.Def TyVarDecl TyName (Provenance a)
tn (PLCRecType uni fun a
-> Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a))
-> m (PLCRecType uni fun a)
-> m (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Recursivity
-> Type TyName uni (Provenance a)
-> Datatype TyName Name uni fun (Provenance a)
-> m (PLCRecType uni fun a)
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
Recursivity
-> PIRType uni a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PLCRecType uni fun a)
mkDatatypeType Recursivity
r Type TyName uni (Provenance a)
pf Datatype TyName Name uni fun (Provenance a)
d
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
constrDefs <- [(VarDecl TyName Name uni fun (Provenance a), Int)]
-> ((VarDecl TyName Name uni fun (Provenance a), Int)
-> m (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)))
-> m [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for ([VarDecl TyName Name uni fun (Provenance a)]
-> [Int] -> [(VarDecl TyName Name uni fun (Provenance a), Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [VarDecl TyName Name uni fun (Provenance a)]
constrs [Int
0..]) (((VarDecl TyName Name uni fun (Provenance a), Int)
-> m (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)))
-> m [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)])
-> ((VarDecl TyName Name uni fun (Provenance a), Int)
-> m (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)))
-> m [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
forall a b. (a -> b) -> a -> b
$ \(VarDecl TyName Name uni fun (Provenance a)
c, Int
i) -> do
let constrTy :: Type TyName uni (Provenance a)
constrTy = Datatype TyName Name uni fun (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a)
forall (uni :: * -> *) fun a.
Datatype TyName Name uni fun (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a) -> PIRType uni a
mkConstructorType Datatype TyName Name uni fun (Provenance a)
d VarDecl TyName Name uni fun (Provenance a)
c
VarDecl TyName Name uni fun (Provenance a)
-> PIRTerm uni fun a
-> Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
forall var val. var -> val -> Def var val
PIR.Def (Provenance a
-> Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
forall k tyname name (uni :: * -> *) (fun :: k) ann.
ann
-> name -> Type tyname uni ann -> VarDecl tyname name uni fun ann
VarDecl (DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
Constructor Provenance a
ann) (VarDecl TyName Name uni fun (Provenance a) -> Name
forall tyname name (uni :: * -> *) k (fun :: k) ann.
VarDecl tyname name uni fun ann -> name
_varDeclName VarDecl TyName Name uni fun (Provenance a)
c) Type TyName uni (Provenance a)
constrTy) (PIRTerm uni fun a
-> Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
-> m (PIRTerm uni fun a)
-> m (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> Int
-> m (PIRTerm uni fun a)
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> Int
-> m (PIRTerm uni fun a)
mkConstructor (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
-> PLCRecType uni fun a
forall var val. Def var val -> val
PIR.defVal Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef) Datatype TyName Name uni fun (Provenance a)
d Int
i
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
destrDef <- do
let destTy :: Type TyName uni (Provenance a)
destTy = Type TyName uni (Provenance a)
-> Datatype TyName Name uni fun (Provenance a)
-> Type TyName uni (Provenance a)
forall (uni :: * -> *) a fun.
PIRType uni a
-> Datatype TyName Name uni fun (Provenance a) -> PIRType uni a
mkDestructorTy Type TyName uni (Provenance a)
pf Datatype TyName Name uni fun (Provenance a)
d
VarDecl TyName Name uni fun (Provenance a)
-> PIRTerm uni fun a
-> Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
forall var val. var -> val -> Def var val
PIR.Def (Provenance a
-> Name
-> Type TyName uni (Provenance a)
-> VarDecl TyName Name uni fun (Provenance a)
forall k tyname name (uni :: * -> *) (fun :: k) ann.
ann
-> name -> Type tyname uni ann -> VarDecl tyname name uni fun ann
VarDecl (DatatypeComponent -> Provenance a -> Provenance a
forall a. DatatypeComponent -> Provenance a -> Provenance a
DatatypeComponent DatatypeComponent
Destructor Provenance a
ann) Name
destr Type TyName uni (Provenance a)
destTy) (PIRTerm uni fun a
-> Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
-> m (PIRTerm uni fun a)
-> m (Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
forall (m :: * -> *) (uni :: * -> *) fun a.
MonadQuote m =>
PLCRecType uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
mkDestructor (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
-> PLCRecType uni fun a
forall var val. Def var val -> val
PIR.defVal Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef) Datatype TyName Name uni fun (Provenance a)
d
(Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
-> m (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a),
[Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)],
Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Def (TyVarDecl TyName (Provenance a)) (PLCRecType uni fun a)
concreteTyDef, [Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)]
constrDefs, Def
(VarDecl TyName Name uni fun (Provenance a)) (PIRTerm uni fun a)
destrDef)
compileRecDatatypes :: Compiling m e uni fun a => PIRTerm uni fun a -> NE.NonEmpty (Datatype TyName Name uni fun (Provenance a)) -> m (PIRTerm uni fun a)
compileRecDatatypes :: PIRTerm uni fun a
-> NonEmpty (Datatype TyName Name uni fun (Provenance a))
-> m (PIRTerm uni fun a)
compileRecDatatypes PIRTerm uni fun a
body NonEmpty (Datatype TyName Name uni fun (Provenance a))
ds = case NonEmpty (Datatype TyName Name uni fun (Provenance a))
ds of
Datatype TyName Name uni fun (Provenance a)
d NE.:| [] -> Recursivity
-> PIRTerm uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
forall (m :: * -> *) e (uni :: * -> *) fun a.
Compiling m e uni fun a =>
Recursivity
-> PIRTerm uni fun a
-> Datatype TyName Name uni fun (Provenance a)
-> m (PIRTerm uni fun a)
compileDatatype Recursivity
Rec PIRTerm uni fun a
body Datatype TyName Name uni fun (Provenance a)
d
NonEmpty (Datatype TyName Name uni fun (Provenance a))
_ -> m (Provenance a)
forall (uni :: * -> *) fun a (m :: * -> *).
MonadReader (CompilationCtx uni fun a) m =>
m (Provenance a)
getEnclosing m (Provenance a)
-> (Provenance a -> m (PIRTerm uni fun a)) -> m (PIRTerm uni fun a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Provenance a
p -> AReview e (Error uni fun (Provenance a))
-> Error uni fun (Provenance a) -> m (PIRTerm uni fun a)
forall e (m :: * -> *) t x.
MonadError e m =>
AReview e t -> t -> m x
throwing AReview e (Error uni fun (Provenance a))
forall r (uni :: * -> *) fun a.
AsError r uni fun a =>
Prism' r (Error uni fun a)
_Error (Error uni fun (Provenance a) -> m (PIRTerm uni fun a))
-> Error uni fun (Provenance a) -> m (PIRTerm uni fun a)
forall a b. (a -> b) -> a -> b
$ Provenance a -> Text -> Error uni fun (Provenance a)
forall (uni :: * -> *) fun a. a -> Text -> Error uni fun a
UnsupportedError Provenance a
p Text
"Mutually recursive datatypes"