1 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 -- | Haskell terms which are interesting
4 -- to pattern-match when optimizing.
5 module Symantic.Parser.Haskell 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 'Haskellable'
37 -- | Final encoding of some Haskell functions
38 -- useful for some optimizations in 'optimizeComb'.
39 class Haskellable (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 'Haskellable'
58 -- | Initial encoding of 'Haskellable'.
60 Haskell :: ValueCode a -> Haskell a
61 (:.) :: Haskell ((b->c) -> (a->b) -> a -> c)
62 (:$) :: Haskell ((a->b) -> a -> b)
63 (:@) :: Haskell (a->b) -> Haskell a -> Haskell b
64 Cons :: Haskell (a -> [a] -> [a])
65 Const :: Haskell (a -> b -> a)
66 Eq :: Eq a => Haskell a -> Haskell (a -> Bool)
67 Flip :: Haskell ((a -> b -> c) -> b -> a -> c)
76 -- Dummy constraint to get the following constraint
77 -- in scope when pattern-matching.
79 ((x -> y -> z) ~ ((b -> c) -> (a -> b) -> a -> c)) =>
80 Haskell x -> Haskell y -> Haskell z
81 pattern (:.@) f g = (:.) :@ f :@ g
84 ((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
85 Haskell x -> Haskell y
86 pattern FlipApp f = Flip :@ f
89 (x ~ (a -> b -> b)) =>
91 pattern FlipConst = FlipApp Const
94 instance Show (Haskell a) where
96 Haskell{} -> showString "Haskell"
97 (:$) -> showString "($)"
100 Function.$ showsPrec 9 f
101 Function.. showString " . "
102 Function.. showsPrec 9 g
103 (:.) -> showString "(.)"
106 Function.$ showsPrec 10 x
107 Function.. showString " : "
108 Function.. showsPrec 10 xs
109 Cons -> showString "cons"
110 Const -> showString "const"
113 Function.$ showString "== "
114 Function.. showsPrec 0 x
115 Flip -> showString "flip"
116 Id -> showString "id"
117 Unit -> showString "()"
120 Function.$ showsPrec 10 f
121 Function.. showString " "
122 Function.. showsPrec 10 x
123 instance Trans Haskell Value where
124 trans = value Function.. trans
125 instance Trans Haskell TH.CodeQ where
126 trans = code Function.. trans
127 instance Trans Haskell ValueCode where
132 (:@) f x -> (.@) (trans f) (trans x)
139 instance Trans ValueCode Haskell where
141 type instance Output Haskell = ValueCode
143 instance Haskellable Haskell where
146 -- Small optimizations, mainly to reduce dump sizes.
148 (Const :@ x) .@ _y = x
149 ((Flip :@ Const) :@ _x) .@ y = y
158 bool b = Haskell (bool b)
159 char c = Haskell (char c)
162 right = Haskell right
163 nothing = Haskell nothing
165 instance Haskellable ValueCode where
166 (.) = ValueCode (.) (.)
167 ($) = ValueCode ($) ($)
168 (.@) f x = ValueCode ((.@) (value f) (value x)) ((.@) (code f) (code x))
169 bool b = ValueCode (bool b) (bool b)
170 char c = ValueCode (char c) (char c)
171 cons = ValueCode cons cons
172 const = ValueCode const const
173 eq x = ValueCode (eq (value x)) (eq (code x))
174 flip = ValueCode flip flip
176 nil = ValueCode nil nil
177 unit = ValueCode unit unit
178 left = ValueCode left left
179 right = ValueCode right right
180 nothing = ValueCode nothing nothing
181 just = ValueCode just just
182 instance Haskellable Value where
183 (.) = Value (Function..)
184 ($) = Value (Function.$)
185 (.@) f x = Value (unValue f (unValue x))
189 const = Value Function.const
190 eq x = Value (unValue x Eq.==)
191 flip = Value Function.flip
192 id = Value Function.id
197 nothing = Value Nothing
199 instance Haskellable TH.CodeQ where
200 (.) = [|| (Function..) ||]
201 ($) = [|| (Function.$) ||]
202 (.@) f x = [|| $$f $$x ||]
206 const = [|| Function.const ||]
207 eq x = [|| ($$x Eq.==) ||]
208 flip = [|| \f x y -> f y x ||]
213 right = [|| Right ||]
214 nothing = [|| Nothing ||]