1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE ScopedTypeVariables #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# LANGUAGE TypeOperators #-}
7 -- | Expression for @if@.
8 module Language.Symantic.Expr.If where
10 import qualified Control.Monad as Monad
12 import Data.Proxy (Proxy(..))
13 import Data.Type.Equality ((:~:)(Refl))
15 import Language.Symantic.Type
16 import Language.Symantic.Repr
17 import Language.Symantic.Expr.Root
18 import Language.Symantic.Expr.Error
19 import Language.Symantic.Expr.From
20 import Language.Symantic.Trans.Common
24 class Sym_If repr where
25 if_ :: repr Bool -> repr a -> repr a -> repr a
26 default if_ :: Trans t repr => t repr Bool -> t repr a -> t repr a -> t repr a
28 instance Sym_If Repr_Host where
29 if_ (Repr_Host b) ok ko = if b then ok else ko
30 instance Sym_If Repr_Text where
31 if_ (Repr_Text cond) (Repr_Text ok) (Repr_Text ko) =
33 let p' = Precedence 2 in
36 " then " <> ok p' v <>
39 instance (Sym_If r1, Sym_If r2) => Sym_If (Repr_Dup r1 r2) where
40 if_ (c1 `Repr_Dup` c2) (ok1 `Repr_Dup` ok2) (ko1 `Repr_Dup` ko2) =
41 if_ c1 ok1 ko1 `Repr_Dup` if_ c2 ok2 ko2
45 class Sym_When repr where
46 when :: repr Bool -> repr () -> repr ()
47 default when :: Trans t repr => t repr Bool -> t repr () -> t repr ()
48 when = trans_map2 when
49 instance Sym_When Repr_Host where
50 when (Repr_Host b) = Monad.when b
51 instance Sym_When Repr_Text where
52 when (Repr_Text cond) (Repr_Text ok) =
54 let p' = Precedence 2 in
56 "when " <> cond p' v <>
58 instance (Sym_When r1, Sym_When r2) => Sym_When (Repr_Dup r1 r2) where
59 when (c1 `Repr_Dup` c2) (ok1 `Repr_Dup` ok2) =
60 when c1 ok1 `Repr_Dup` when c2 ok2
64 data Expr_If (root:: *)
65 type instance Root_of_Expr (Expr_If root) = root
66 type instance Type_of_Expr (Expr_If root) = No_Type
67 type instance Sym_of_Expr (Expr_If root) repr = (Sym_If repr)
68 type instance Error_of_Expr ast (Expr_If root) = No_Error_Expr
71 :: forall root ty ast hs ret.
72 ( ty ~ Type_Root_of_Expr (Expr_If root)
74 , Type0_Lift Type_Bool (Type_of_Expr root)
76 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
77 (Error_of_Expr ast root)
78 , Root_of_Expr root ~ root
79 ) => ast -> ast -> ast
80 -> ExprFrom ast (Expr_If root) hs ret
81 if_from ast_cond ast_ok ast_ko ex ast ctx k =
82 expr_from (Proxy::Proxy root) ast_cond ctx $
83 \(ty_cond::ty h_n) (Forall_Repr_with_Context cond) ->
84 expr_from (Proxy::Proxy root) ast_ok ctx $
85 \(ty_ok::ty h_ok) (Forall_Repr_with_Context ok) ->
86 expr_from (Proxy::Proxy root) ast_ko ctx $
87 \(ty_ko::ty h_ko) (Forall_Repr_with_Context ko) ->
88 check_type0_eq ex ast type_bool ty_cond $ \Refl ->
89 check_type0_eq ex ast ty_ok ty_ko $ \Refl ->
90 k ty_ok $ Forall_Repr_with_Context $
91 \c -> if_ (cond c) (ok c) (ko c)
95 data Expr_When (root:: *)
96 type instance Root_of_Expr (Expr_When root) = root
97 type instance Type_of_Expr (Expr_When root) = No_Type
98 type instance Sym_of_Expr (Expr_When root) repr = (Sym_When repr)
99 type instance Error_of_Expr ast (Expr_When root) = No_Error_Expr
102 :: forall root ty ast hs ret.
103 ( ty ~ Type_Root_of_Expr (Expr_When root)
105 , Type0_Lift Type_Bool (Type_of_Expr root)
106 , Type0_Lift Type_Unit (Type_of_Expr root)
108 , Error_Expr_Lift (Error_Expr (Error_of_Type ast ty) ty ast)
109 (Error_of_Expr ast root)
110 , Root_of_Expr root ~ root
112 -> ExprFrom ast (Expr_When root) hs ret
113 when_from ast_cond ast_ok ex ast ctx k =
114 expr_from (Proxy::Proxy root) ast_cond ctx $
115 \(ty_cond::ty h_n) (Forall_Repr_with_Context cond) ->
116 expr_from (Proxy::Proxy root) ast_ok ctx $
117 \(ty_ok::ty h_ok) (Forall_Repr_with_Context ok) ->
118 check_type0_eq ex ast type_bool ty_cond $ \Refl ->
119 check_type0_eq ex ast type_unit ty_ok $ \Refl ->
120 k ty_ok $ Forall_Repr_with_Context $
121 \c -> when (cond c) (ok c)