1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE MultiParamTypeClasses #-}
5 {-# LANGUAGE ScopedTypeVariables #-}
6 {-# LANGUAGE TypeFamilies #-}
7 -- | Expression for 'Maybe'.
8 module Language.Symantic.Expr.Maybe where
10 import Data.Proxy (Proxy(..))
11 import Data.Type.Equality ((:~:)(Refl))
12 import Prelude hiding (maybe)
13 import Language.Symantic.Type
14 import Language.Symantic.Repr.Dup
15 import Language.Symantic.Trans.Common
16 import Language.Symantic.Expr.Common
17 import Language.Symantic.Expr.Lambda
18 import Language.Symantic.Expr.Bool
20 -- * Class 'Sym_Maybe'
22 class Sym_Maybe lam repr where
25 -> repr (Lambda lam a b)
32 -> t repr (Lambda lam a b)
35 maybe = trans_map3 maybe
37 class Sym_Maybe_Cons repr where
38 nothing :: repr (Maybe a)
39 just :: repr a -> repr (Maybe a)
41 default nothing :: Trans t repr => t repr (Maybe a)
42 default just :: Trans t repr => t repr a -> t repr (Maybe a)
43 nothing = trans_lift nothing
44 just = trans_map1 just
46 instance -- Sym_Maybe Dup
49 ) => Sym_Maybe lam (Dup r1 r2) where
50 maybe (m1 `Dup` m2) (n1 `Dup` n2) (j1 `Dup` j2) =
51 maybe m1 n1 j1 `Dup` maybe m2 n2 j2
52 instance -- Sym_Maybe_Cons Dup
55 ) => Sym_Maybe_Cons (Dup r1 r2) where
56 nothing = nothing `Dup` nothing
57 just (a1 `Dup` a2) = just a1 `Dup` just a2
59 -- * Type 'Expr_Maybe'
61 data Expr_Maybe (lam:: * -> *) (root:: *)
62 type instance Root_of_Expr (Expr_Maybe lam root) = root
63 type instance Type_of_Expr (Expr_Maybe lam root) = Type_Maybe
64 type instance Sym_of_Expr (Expr_Maybe lam root) repr = (Sym_Maybe lam repr, Sym_Maybe_Cons repr)
65 type instance Error_of_Expr ast (Expr_Maybe lam root) = No_Error_Expr
68 :: forall root lam ty ast hs ret.
69 ( ty ~ Type_Root_of_Expr (Expr_Maybe lam root)
70 , Type_Eq (Type_Root_of_Expr root)
72 , Type_Root_Lift (Type_Fun lam) (Type_Root_of_Expr root)
73 , Type_Root_Lift Type_Maybe (Type_Root_of_Expr root)
74 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
75 (Error_of_Expr ast root)
76 , Type_Unlift (Type_Fun lam) (Type_of_Expr root)
77 , Type_Unlift Type_Maybe (Type_of_Expr root)
78 , Root_of_Expr root ~ root
79 ) => ast -> ast -> ast
80 -> Expr_From ast (Expr_Maybe lam root) hs ret
81 maybe_from ast_n ast_j ast_m ex ast ctx k =
82 expr_from (Proxy::Proxy root) ast_n ctx $
83 \(ty_n::Type_Root_of_Expr root h_n) (Forall_Repr_with_Context n) ->
84 expr_from (Proxy::Proxy root) ast_j ctx $
85 \(ty_j::Type_Root_of_Expr root h_j) (Forall_Repr_with_Context j) ->
86 expr_from (Proxy::Proxy root) ast_m ctx $
87 \(ty_m::Type_Root_of_Expr root h_m) (Forall_Repr_with_Context m) ->
88 case type_unlift $ unType_Root ty_j of
91 Error_Expr_Type_mismatch ast
92 (Exists_Type (type_var SZero `type_fun` type_var (SSucc SZero)
93 :: Type_Root_of_Expr (Expr_Maybe lam root) (lam Zero -> lam (Succ Zero))))
95 Just (ty_j_a `Type_Fun` ty_j_b
96 :: Type_Fun lam (Type_Root_of_Expr root) h_j) ->
97 case type_unlift $ unType_Root ty_m of
100 Error_Expr_Type_mismatch ast
101 (Exists_Type (type_maybe $ type_var SZero
102 :: Type_Root_of_Expr (Expr_Maybe lam root) (Maybe Zero)))
104 Just (Type_Maybe ty_m_a
105 :: Type_Maybe (Type_Root_of_Expr root) h_m) ->
107 ty_n ty_j_b $ \Refl ->
109 ty_m_a ty_j_a $ \Refl ->
110 k ty_n $ Forall_Repr_with_Context $
111 \c -> maybe (n c) (j c) (m c)
114 :: forall root lam ty ast hs ret.
115 ( ty ~ Type_Root_of_Expr (Expr_Maybe lam root)
116 , Type_from ast (Type_Root_of_Expr root)
117 , Type_Root_Lift Type_Maybe (Type_Root_of_Expr root)
118 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
119 (Error_of_Expr ast root)
120 , Root_of_Expr root ~ root
122 -> Expr_From ast (Expr_Maybe lam root) hs ret
123 nothing_from ast_ty_a ex ast _ctx k =
125 (Proxy::Proxy (Type_Root_of_Expr root))
126 ast_ty_a (Right . Exists_Type) of
127 Left err -> Left $ error_expr ex $ Error_Expr_Type err ast
128 Right (Exists_Type (ty_a::Type_Root_of_Expr root h_a)) ->
129 k (type_maybe ty_a) $ Forall_Repr_with_Context $
133 :: forall root lam ty ast hs ret.
134 ( ty ~ Type_Root_of_Expr (Expr_Maybe lam root)
136 , Type_Root_Lift Type_Maybe (Type_Root_of_Expr root)
137 , Root_of_Expr root ~ root
139 -> Expr_From ast (Expr_Maybe lam root) hs ret
140 just_from ast_a _ex _ast ctx k =
141 expr_from (Proxy::Proxy root) ast_a ctx $
142 \(ty_a::Type_Root_of_Expr root h_a) (Forall_Repr_with_Context a) ->
143 k (type_maybe ty_a) $ Forall_Repr_with_Context $
146 -- ** Type 'Expr_Lambda_Maybe_Bool'
147 -- | Convenient alias.
148 type Expr_Lambda_Maybe_Bool lam
149 = Expr_Root (Expr_Alt (Expr_Lambda lam)
150 (Expr_Alt (Expr_Maybe lam)
153 -- | Convenient alias around 'expr_from'.
154 expr_lambda_maybe_bool_from
155 :: forall lam ast root.
156 ( Expr_from ast (Expr_Lambda_Maybe_Bool lam)
157 , root ~ Expr_Lambda_Maybe_Bool lam
160 -> Either (Error_of_Expr ast root)
161 (Exists_Type_and_Repr (Type_Root_of_Expr root)
163 expr_lambda_maybe_bool_from _lam ast =
164 expr_from (Proxy::Proxy root) ast
165 Context_Empty $ \ty (Forall_Repr_with_Context repr) ->
166 Right $ Exists_Type_and_Repr ty $
167 Forall_Repr $ repr Context_Empty