1 {-# LANGUAGE UndecidableInstances #-}
2 {-# OPTIONS_GHC -fno-warn-orphans #-}
3 -- | Symantic for 'Num'.
4 module Language.Symantic.Lib.Num where
6 import Control.Monad (liftM, liftM2)
7 import qualified Data.Function as Fun
9 import Data.Type.Equality ((:~:)(Refl))
10 import qualified Prelude
11 import Prelude hiding (Num(..))
14 import Language.Symantic.Parsing
15 import Language.Symantic.Typing
16 import Language.Symantic.Compiling
17 import Language.Symantic.Interpreting
18 import Language.Symantic.Transforming
19 import Language.Symantic.Lib.Lambda
22 class Sym_Num term where
23 abs :: Num n => term n -> term n
24 negate :: Num n => term n -> term n
25 signum :: Num n => term n -> term n
26 (+) :: Num n => term n -> term n -> term n; infixl 6 +
27 (-) :: Num n => term n -> term n -> term n; infixl 6 -
28 (*) :: Num n => term n -> term n -> term n; infixl 7 *
29 fromInteger :: Num n => term Integer -> term n
31 default abs :: (Trans t term, Num n) => t term n -> t term n
32 default negate :: (Trans t term, Num n) => t term n -> t term n
33 default signum :: (Trans t term, Num n) => t term n -> t term n
34 default (+) :: (Trans t term, Num n) => t term n -> t term n -> t term n
35 default (-) :: (Trans t term, Num n) => t term n -> t term n -> t term n
36 default (*) :: (Trans t term, Num n) => t term n -> t term n -> t term n
37 default fromInteger :: (Trans t term, Num n) => t term Integer -> t term n
40 negate = trans_map1 negate
41 signum = trans_map1 signum
45 fromInteger = trans_map1 fromInteger
47 type instance Sym_of_Iface (Proxy Num) = Sym_Num
48 type instance TyConsts_of_Iface (Proxy Num) = Proxy Num ': TyConsts_imported_by Num
49 type instance TyConsts_imported_by Num =
53 instance Sym_Num HostI where
54 abs = liftM Prelude.abs
55 negate = liftM Prelude.negate
56 signum = liftM Prelude.signum
57 (+) = liftM2 (Prelude.+)
58 (-) = liftM2 (Prelude.-)
59 (*) = liftM2 (Prelude.*)
60 fromInteger = liftM Prelude.fromInteger
61 instance Sym_Num TextI where
63 negate = textI1 "negate"
64 signum = textI1 "signum"
65 (+) = textI_infix "+" (infixB L 6)
66 (-) = textI_infix "-" (infixL 6)
67 (*) = textI_infix "*" (infixB L 7)
68 fromInteger = textI1 "fromInteger"
69 instance (Sym_Num r1, Sym_Num r2) => Sym_Num (DupI r1 r2) where
70 abs = dupI1 @Sym_Num abs
71 negate = dupI1 @Sym_Num negate
72 signum = dupI1 @Sym_Num signum
73 (+) = dupI2 @Sym_Num (+)
74 (-) = dupI2 @Sym_Num (-)
75 (*) = dupI2 @Sym_Num (*)
76 fromInteger = dupI1 @Sym_Num fromInteger
79 ( Read_TyNameR TyName cs rs
81 ) => Read_TyNameR TyName cs (Proxy Num ': rs) where
82 read_TyNameR _cs (TyName "Num") k = k (ty @Num)
83 read_TyNameR _rs raw k = read_TyNameR (Proxy @rs) raw k
84 instance Show_TyConst cs => Show_TyConst (Proxy Num ': cs) where
85 show_TyConst TyConstZ{} = "Num"
86 show_TyConst (TyConstS c) = show_TyConst c
88 instance Proj_TyConC cs (Proxy Num)
89 data instance TokenT meta (ts::[*]) (Proxy Num)
90 = Token_Term_Num_abs (EToken meta ts)
91 | Token_Term_Num_negate (EToken meta ts)
92 | Token_Term_Num_signum (EToken meta ts)
93 | Token_Term_Num_add (EToken meta ts)
94 | Token_Term_Num_sub (EToken meta ts)
95 | Token_Term_Num_mul (EToken meta ts)
96 | Token_Term_Num_fromInteger (EToken meta '[Proxy Token_Type])
97 deriving instance (Eq meta, Eq_Token meta ts) => Eq (TokenT meta ts (Proxy Num))
98 deriving instance (Show meta, Show_Token meta ts) => Show (TokenT meta ts (Proxy Num))
100 ( Read_TyName TyName (TyConsts_of_Ifaces is)
101 , Inj_TyConst (TyConsts_of_Ifaces is) Num
102 , Inj_TyConst (TyConsts_of_Ifaces is) (->)
103 , Inj_TyConst (TyConsts_of_Ifaces is) Integer
104 , Proj_TyCon (TyConsts_of_Ifaces is)
106 ) => CompileI is (Proxy Num) where
109 Token_Term_Num_abs tok_a -> op1_from tok_a abs
110 Token_Term_Num_negate tok_a -> op1_from tok_a negate
111 Token_Term_Num_signum tok_a -> op1_from tok_a signum
112 Token_Term_Num_add tok_a -> op2_from tok_a (+)
113 Token_Term_Num_sub tok_a -> op2_from tok_a (-)
114 Token_Term_Num_mul tok_a -> op2_from tok_a (*)
115 Token_Term_Num_fromInteger tok_ty_a ->
116 -- fromInteger :: Num a => Integer -> a
117 compile_Type tok_ty_a $ \(ty_a::Type (TyConsts_of_Ifaces is) a) ->
120 (At (Just tok_ty_a) $ kind_of ty_a) $ \Refl ->
121 check_TyCon (At (Just tok_ty_a) (ty @Num :$ ty_a)) $ \TyCon ->
122 k (ty @Integer ~> ty_a) $ TermO $
123 Fun.const $ lam fromInteger
126 (op::forall term a. (Sym_Num term, Num a)
127 => term a -> term a) =
128 -- abs :: Num a => a -> a
129 -- negate :: Num a => a -> a
130 -- signum :: Num a => a -> a
131 compileO tok_a ctx $ \ty_a (TermO x) ->
132 check_TyCon (At (Just tok_a) (ty @Num :$ ty_a)) $ \TyCon ->
136 (op::forall term a. (Sym_Num term, Num a)
137 => term a -> term a -> term a) =
138 -- (+) :: Num a => a -> a -> a
139 -- (-) :: Num a => a -> a -> a
140 -- (*) :: Num a => a -> a -> a
141 compileO tok_a ctx $ \ty_a (TermO x) ->
142 check_TyCon (At (Just tok_a) (ty @Num :$ ty_a)) $ \TyCon ->
143 k (ty_a ~> ty_a) $ TermO $
144 \c -> lam $ \y -> op (x c) y
145 instance -- TokenizeT
146 Inj_Token meta ts Num =>
147 TokenizeT meta ts (Proxy Num) where
148 tokenizeT _t = mempty
149 { tokenizers_infix = tokenizeTMod []
150 [ tokenize1 "abs" infixN5 Token_Term_Num_abs
151 , tokenize1 "negate" infixN5 Token_Term_Num_negate
152 , tokenize1 "signum" infixN5 Token_Term_Num_signum
153 , tokenize1 "+" (infixB L 6) Token_Term_Num_add
154 , tokenize1 "-" (infixL 6) Token_Term_Num_sub
155 , tokenize1 "*" (infixB L 7) Token_Term_Num_mul
156 , (Term_Name "fromInteger",) Term_ProTok
157 { term_protok = \meta -> ProTokPi $ \a ->
158 ProTok $ inj_EToken meta $ Token_Term_Num_fromInteger a
159 , term_fixity = infixN5
162 , tokenizers_prefix = tokenizeTMod []
163 [ tokenize1 "-" (Prefix 10) Token_Term_Num_negate
166 instance Gram_Term_AtomsT meta ts (Proxy Num) g