{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} module Language.LOL.Symantic.Expr.If where import Data.Proxy (Proxy(..)) import Data.Type.Equality ((:~:)(Refl)) import Language.LOL.Symantic.Expr.Bool import Language.LOL.Symantic.Expr.Common import Language.LOL.Symantic.Expr.Lambda import Language.LOL.Symantic.Repr.Dup import Language.LOL.Symantic.Trans.Common import Language.LOL.Symantic.Type -- * Class 'Sym_If' class Sym_If repr where if_ :: repr Bool -> repr a -> repr a -> repr a default if_ :: Trans t repr => t repr Bool -> t repr a -> t repr a -> t repr a if_ = trans_map3 if_ class Sym_When repr where when :: repr Bool -> repr () -> repr () default when :: Trans t repr => t repr Bool -> t repr () -> t repr () when = trans_map2 when instance -- Sym_If Dup ( Sym_If r1 , Sym_If r2 ) => Sym_If (Dup r1 r2) where if_ (c1 `Dup` c2) (ok1 `Dup` ok2) (ko1 `Dup` ko2) = if_ c1 ok1 ko1 `Dup` if_ c2 ok2 ko2 instance -- Sym_When Dup ( Sym_When r1 , Sym_When r2 ) => Sym_When (Dup r1 r2) where when (c1 `Dup` c2) (ok1 `Dup` ok2) = when c1 ok1 `Dup` when c2 ok2 -- * Type 'Expr_If' -- | Expression. data Expr_If (root:: *) type instance Root_of_Expr (Expr_If root) = root type instance Type_of_Expr (Expr_If root) = No_Type type instance Sym_of_Expr (Expr_If root) repr = (Sym_If repr) type instance Error_of_Expr ast (Expr_If root) = No_Error_Expr if_from :: forall root ty ast hs ret. ( ty ~ Type_Root_of_Expr (Expr_If root) , Type_Root_Lift Type_Bool (Type_Root_of_Expr root) , Type_Eq (Type_Root_of_Expr root) , Expr_from ast root , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast) (Error_of_Expr ast root) , Root_of_Expr root ~ root ) => ast -> ast -> ast -> Expr_From ast (Expr_If root) hs ret if_from ast_cond ast_ok ast_ko ex ast ctx k = expr_from (Proxy::Proxy root) ast_cond ctx $ \(ty_cond::Type_Root_of_Expr root h_n) (Forall_Repr_with_Context cond) -> expr_from (Proxy::Proxy root) ast_ok ctx $ \(ty_ok::Type_Root_of_Expr root h_ok) (Forall_Repr_with_Context ok) -> expr_from (Proxy::Proxy root) ast_ko ctx $ \(ty_ko::Type_Root_of_Expr root h_ko) (Forall_Repr_with_Context ko) -> when_type_eq ex ast type_bool ty_cond $ \Refl -> when_type_eq ex ast ty_ok ty_ko $ \Refl -> k ty_ok $ Forall_Repr_with_Context $ \c -> if_ (cond c) (ok c) (ko c) -- * Type 'Expr_When' -- | Expression. data Expr_When (root:: *) type instance Root_of_Expr (Expr_When root) = root type instance Type_of_Expr (Expr_When root) = No_Type type instance Sym_of_Expr (Expr_When root) repr = (Sym_When repr) type instance Error_of_Expr ast (Expr_When root) = No_Error_Expr when_from :: forall root ty ast hs ret. ( ty ~ Type_Root_of_Expr (Expr_When root) , Type_Root_Lift Type_Bool (Type_Root_of_Expr root) , Type_Root_Lift Type_Unit (Type_Root_of_Expr root) , Type_Eq (Type_Root_of_Expr root) , Expr_from ast root , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast) (Error_of_Expr ast root) , Root_of_Expr root ~ root ) => ast -> ast -> Expr_From ast (Expr_When root) hs ret when_from ast_cond ast_ok ex ast ctx k = expr_from (Proxy::Proxy root) ast_cond ctx $ \(ty_cond::Type_Root_of_Expr root h_n) (Forall_Repr_with_Context cond) -> expr_from (Proxy::Proxy root) ast_ok ctx $ \(ty_ok::Type_Root_of_Expr root h_ok) (Forall_Repr_with_Context ok) -> when_type_eq ex ast type_bool ty_cond $ \Refl -> when_type_eq ex ast type_unit ty_ok $ \Refl -> k ty_ok $ Forall_Repr_with_Context $ \c -> when (cond c) (ok c) -- ** Type 'Expr_Lambda_Bool_If' -- | Convenient alias. type Expr_Lambda_If_Bool lam = Expr_Root (Expr_Alt (Expr_Lambda lam) (Expr_Alt Expr_If Expr_Bool)) -- | Convenient alias around 'expr_from'. expr_lambda_if_bool_from :: forall lam ast root. ( Expr_from ast (Expr_Lambda_If_Bool lam) , root ~ Expr_Lambda_If_Bool lam ) => Proxy lam -> ast -> Either (Error_of_Expr ast root) (Exists_Type_and_Repr (Type_Root_of_Expr root) (Forall_Repr root)) expr_lambda_if_bool_from _lam ast = expr_from (Proxy::Proxy root) ast Context_Empty $ \ty (Forall_Repr_with_Context repr) -> Right $ Exists_Type_and_Repr ty $ Forall_Repr $ repr Context_Empty