1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE MultiParamTypeClasses #-}
5 {-# LANGUAGE OverloadedStrings #-}
6 {-# LANGUAGE Rank2Types #-}
7 {-# LANGUAGE ScopedTypeVariables #-}
8 {-# LANGUAGE TypeFamilies #-}
9 {-# LANGUAGE TypeOperators #-}
10 {-# LANGUAGE UndecidableInstances #-}
11 {-# OPTIONS_GHC -fno-warn-orphans #-}
12 -- | Symantic for 'Bool'.
13 module Language.Symantic.Compiling.Bool where
16 import qualified Data.Bool as Bool
19 import Data.Type.Equality ((:~:)(Refl))
20 import qualified Data.Text as Text
21 import Prelude hiding ((&&), not, (||))
23 import Language.Symantic.Typing
24 import Language.Symantic.Compiling.Term
25 import Language.Symantic.Interpreting
26 import Language.Symantic.Transforming.Trans
30 class Sym_Bool term where
31 bool :: Bool -> term Bool
32 not :: term Bool -> term Bool
33 (&&) :: term Bool -> term Bool -> term Bool
34 (||) :: term Bool -> term Bool -> term Bool
35 xor :: term Bool -> term Bool -> term Bool
36 xor x y = (x || y) && not (x && y)
38 default bool :: Trans t term => Bool -> t term Bool
39 default not :: Trans t term => t term Bool -> t term Bool
40 default (&&) :: Trans t term => t term Bool -> t term Bool -> t term Bool
41 default (||) :: Trans t term => t term Bool -> t term Bool -> t term Bool
43 bool = trans_lift . bool
45 (&&) = trans_map2 (&&)
46 (||) = trans_map2 (||)
52 type instance Sym_of_Iface (Proxy Bool) = Sym_Bool
54 instance Sym_Bool HostI where
57 (&&) = liftM2 (Bool.&&)
58 (||) = liftM2 (Bool.||)
59 instance Sym_Bool TextI where
60 bool a = TextI $ \_p _v ->
64 let p' = Precedence 9 in
65 paren p p' $ "not " <> x p' v
66 (&&) = textI_infix "&&" (Precedence 6)
67 (||) = textI_infix "||" (Precedence 5)
68 xor = textI_infix "`xor`" (Precedence 5)
69 instance (Sym_Bool r1, Sym_Bool r2) => Sym_Bool (DupI r1 r2) where
70 bool x = bool x `DupI` bool x
71 not = dupI1 sym_Bool not
72 (&&) = dupI2 sym_Bool (&&)
73 (||) = dupI2 sym_Bool (||)
74 xor = dupI2 sym_Bool xor
76 sym_Bool :: Proxy Sym_Bool
79 instance -- Term_fromI
81 , Lexem ast ~ LamVarName
82 , Inj_Const (Consts_of_Ifaces is) Bool
83 , Inj_Const (Consts_of_Ifaces is) (->)
85 ) => Term_fromI is (Proxy Bool) ast where
86 term_fromI ast ctx k =
88 "True" -> k tyBool $ Term_of_LamCtx $ \_c -> bool True
89 "False" -> k tyBool $ Term_of_LamCtx $ \_c -> bool False
94 _ -> Left $ Error_Term_unsupported
96 op1_from (op::forall term. Sym_Bool term => term Bool -> term Bool) =
98 [] -> k (tyBool ~> tyBool) $ Term_of_LamCtx $
101 term_from ast_x ctx $ \ty_x (Term_of_LamCtx x) ->
102 check_type (At Nothing tyBool) (At (Just ast_x) ty_x) $ \Refl ->
103 k tyBool $ Term_of_LamCtx $
105 _ -> Left $ Error_Term_Syntax $
106 Error_Syntax_too_many_arguments $ At (Just ast) 1
107 op2_from (op::forall term. Sym_Bool term => term Bool -> term Bool -> term Bool) =
108 case ast_nodes ast of
109 [] -> k (tyBool ~> tyBool ~> tyBool) $ Term_of_LamCtx $
110 \_c -> lam $ lam . op
112 term_from ast_x ctx $ \ty_x (Term_of_LamCtx x) ->
113 check_type (At Nothing tyBool) (At (Just ast_x) ty_x) $ \Refl ->
114 k (tyBool ~> tyBool) $ Term_of_LamCtx $
117 term_from ast_x ctx $ \ty_x (Term_of_LamCtx x) ->
118 term_from ast_y ctx $ \ty_y (Term_of_LamCtx y) ->
119 check_type (At Nothing tyBool) (At (Just ast_x) ty_x) $ \Refl ->
120 check_type (At Nothing tyBool) (At (Just ast_y) ty_y) $ \Refl ->
121 k tyBool $ Term_of_LamCtx $
123 _ -> Left $ Error_Term_Syntax $
124 Error_Syntax_too_many_arguments $ At (Just ast) 2