1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE ScopedTypeVariables #-}
4 {-# LANGUAGE TypeFamilies #-}
5 {-# LANGUAGE TypeOperators #-}
6 -- | Expression for @if@.
7 module Language.Symantic.Expr.If where
9 import Data.Proxy (Proxy(..))
10 import Data.Type.Equality ((:~:)(Refl))
11 import Language.Symantic.Expr.Common
12 import Language.Symantic.Trans.Common
13 import Language.Symantic.Type
17 class Sym_If repr where
18 if_ :: repr Bool -> repr a -> repr a -> repr a
19 default if_ :: Trans t repr => t repr Bool -> t repr a -> t repr a -> t repr a
24 class Sym_When repr where
25 when :: repr Bool -> repr () -> repr ()
26 default when :: Trans t repr => t repr Bool -> t repr () -> t repr ()
27 when = trans_map2 when
31 data Expr_If (root:: *)
32 type instance Root_of_Expr (Expr_If root) = root
33 type instance Type_of_Expr (Expr_If root) = No_Type
34 type instance Sym_of_Expr (Expr_If root) repr = (Sym_If repr)
35 type instance Error_of_Expr ast (Expr_If root) = No_Error_Expr
38 :: forall root ty ast hs ret.
39 ( ty ~ Type_Root_of_Expr (Expr_If root)
41 , Lift_Type_Root Type_Bool (Type_Root_of_Expr root)
43 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
44 (Error_of_Expr ast root)
45 , Root_of_Expr root ~ root
46 ) => ast -> ast -> ast
47 -> Expr_From ast (Expr_If root) hs ret
48 if_from ast_cond ast_ok ast_ko ex ast ctx k =
49 expr_from (Proxy::Proxy root) ast_cond ctx $
50 \(ty_cond::Type_Root_of_Expr root h_n) (Forall_Repr_with_Context cond) ->
51 expr_from (Proxy::Proxy root) ast_ok ctx $
52 \(ty_ok::Type_Root_of_Expr root h_ok) (Forall_Repr_with_Context ok) ->
53 expr_from (Proxy::Proxy root) ast_ko ctx $
54 \(ty_ko::Type_Root_of_Expr root h_ko) (Forall_Repr_with_Context ko) ->
55 check_eq_type ex ast type_bool ty_cond $ \Refl ->
56 check_eq_type ex ast ty_ok ty_ko $ \Refl ->
57 k ty_ok $ Forall_Repr_with_Context $
58 \c -> if_ (cond c) (ok c) (ko c)
62 data Expr_When (root:: *)
63 type instance Root_of_Expr (Expr_When root) = root
64 type instance Type_of_Expr (Expr_When root) = No_Type
65 type instance Sym_of_Expr (Expr_When root) repr = (Sym_When repr)
66 type instance Error_of_Expr ast (Expr_When root) = No_Error_Expr
69 :: forall root ty ast hs ret.
70 ( ty ~ Type_Root_of_Expr (Expr_When root)
72 , Lift_Type_Root Type_Bool (Type_Root_of_Expr root)
73 , Lift_Type_Root Type_Unit (Type_Root_of_Expr root)
75 , Lift_Error_Expr (Error_Expr (Error_of_Type ast ty) ty ast)
76 (Error_of_Expr ast root)
77 , Root_of_Expr root ~ root
79 -> Expr_From ast (Expr_When root) hs ret
80 when_from ast_cond ast_ok ex ast ctx k =
81 expr_from (Proxy::Proxy root) ast_cond ctx $
82 \(ty_cond::Type_Root_of_Expr root h_n) (Forall_Repr_with_Context cond) ->
83 expr_from (Proxy::Proxy root) ast_ok ctx $
84 \(ty_ok::Type_Root_of_Expr root h_ok) (Forall_Repr_with_Context ok) ->
85 check_eq_type ex ast type_bool ty_cond $ \Refl ->
86 check_eq_type ex ast type_unit ty_ok $ \Refl ->
87 k ty_ok $ Forall_Repr_with_Context $
88 \c -> when (cond c) (ok c)