1 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 -- | Haskell terms which are interesting
4 -- to pattern-match when optimizing.
5 module Symantic.Parser.Grammar.Pure where
7 import Data.Bool (Bool(..))
8 import Data.Either (Either(..))
10 import Data.Maybe (Maybe(..))
11 import Data.Ord (Ord(..))
12 import Data.Kind (Type)
13 import Text.Show (Show(..), showParen, showString)
14 import qualified Data.Eq as Eq
15 import qualified Data.Function as Function
16 import qualified Language.Haskell.TH as TH
17 import qualified Language.Haskell.TH.Syntax as TH
19 import Symantic.Univariant.Trans
22 -- | Compile-time 'value' and corresponding 'code'
23 -- (that can produce that value at runtime).
24 data ValueCode a = ValueCode
28 getValue :: ValueCode a -> a
29 getValue = unValue Function.. value
30 getCode :: ValueCode a -> TH.CodeQ a
34 newtype Value a = Value { unValue :: a }
36 -- * Class 'CombPurable'
37 -- | Final encoding of 'CombPure',
38 -- extended with useful terms.
39 class CombPurable (repr :: Type -> Type) where
40 (.) :: repr ((b->c) -> (a->b) -> a -> c)
41 ($) :: repr ((a->b) -> a -> b)
42 (.@) :: repr (a->b) -> repr a -> repr b
43 bool :: Bool -> repr Bool
44 char :: TH.Lift tok => tok -> repr tok
45 cons :: repr (a -> [a] -> [a])
46 const :: repr (a -> b -> a)
47 eq :: Eq a => repr a -> repr (a -> Bool)
48 flip :: repr ((a -> b -> c) -> b -> a -> c)
52 left :: repr (l -> Either l r)
53 right :: repr (r -> Either l r)
54 nothing :: repr (Maybe a)
55 just :: repr (a -> Maybe a)
57 -- ** Type 'CombPurable'
58 -- | Initial encoding of 'CombPurable',
59 -- useful for some optimizations in 'optimizeComb'.
61 CombPure :: ValueCode a -> CombPure a
62 (:.) :: CombPure ((b->c) -> (a->b) -> a -> c)
63 (:$) :: CombPure ((a->b) -> a -> b)
64 (:@) :: CombPure (a->b) -> CombPure a -> CombPure b
65 Cons :: CombPure (a -> [a] -> [a])
66 Const :: CombPure (a -> b -> a)
67 Eq :: Eq a => CombPure a -> CombPure (a -> Bool)
68 Flip :: CombPure ((a -> b -> c) -> b -> a -> c)
77 -- Dummy constraint to get the following constraint
78 -- in scope when pattern-matching.
80 ((x -> y -> z) ~ ((b -> c) -> (a -> b) -> a -> c)) =>
81 CombPure x -> CombPure y -> CombPure z
82 pattern (:.@) f g = (:.) :@ f :@ g
85 ((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
86 CombPure x -> CombPure y
87 pattern FlipApp f = Flip :@ f
90 (x ~ (a -> b -> b)) =>
92 pattern FlipConst = FlipApp Const
95 instance Show (CombPure a) where
97 CombPure{} -> showString "CombPure"
98 (:$) -> showString "($)"
101 Function.$ showsPrec 9 f
102 Function.. showString " . "
103 Function.. showsPrec 9 g
104 (:.) -> showString "(.)"
107 Function.$ showsPrec 10 x
108 Function.. showString " : "
109 Function.. showsPrec 10 xs
110 Cons -> showString "cons"
111 Const -> showString "const"
114 Function.$ showString "== "
115 Function.. showsPrec 0 x
116 Flip -> showString "flip"
117 Id -> showString "id"
118 Unit -> showString "()"
121 Function.$ showsPrec 10 f
122 Function.. showString " "
123 Function.. showsPrec 10 x
125 instance Trans CombPure TH.CodeQ where
126 trans = code Function.. trans
127 instance Trans CombPure Value where
128 trans = value Function.. trans
129 instance Trans CombPure ValueCode where
134 (:@) f x -> (.@) (trans f) (trans x)
141 instance Trans ValueCode CombPure where
143 type instance Output CombPure = ValueCode
145 instance CombPurable CombPure where
148 -- Small optimizations, mainly to reduce dump sizes.
150 (Const :@ x) .@ _y = x
151 ((Flip :@ Const) :@ _x) .@ y = y
160 bool b = CombPure (bool b)
161 char c = CombPure (char c)
164 right = CombPure right
165 nothing = CombPure nothing
167 instance CombPurable ValueCode where
168 (.) = ValueCode (.) (.)
169 ($) = ValueCode ($) ($)
170 (.@) f x = ValueCode ((.@) (value f) (value x)) ((.@) (code f) (code x))
171 bool b = ValueCode (bool b) (bool b)
172 char c = ValueCode (char c) (char c)
173 cons = ValueCode cons cons
174 const = ValueCode const const
175 eq x = ValueCode (eq (value x)) (eq (code x))
176 flip = ValueCode flip flip
178 nil = ValueCode nil nil
179 unit = ValueCode unit unit
180 left = ValueCode left left
181 right = ValueCode right right
182 nothing = ValueCode nothing nothing
183 just = ValueCode just just
184 instance CombPurable Value where
185 (.) = Value (Function..)
186 ($) = Value (Function.$)
187 (.@) f x = Value (unValue f (unValue x))
191 const = Value Function.const
192 eq x = Value (unValue x Eq.==)
193 flip = Value Function.flip
194 id = Value Function.id
199 nothing = Value Nothing
201 instance CombPurable TH.CodeQ where
202 (.) = [|| (Function..) ||]
203 ($) = [|| (Function.$) ||]
204 (.@) f x = [|| $$f $$x ||]
208 const = [|| Function.const ||]
209 eq x = [|| ($$x Eq.==) ||]
210 flip = [|| \f x y -> f y x ||]
215 right = [|| Right ||]
216 nothing = [|| Nothing ||]