1 {-# LANGUAGE DefaultSignatures #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 -- | Haskell terms which are interesting
4 -- to pattern-match when optimizing.
5 module Symantic.Parser.Haskell.Term where
7 import Data.Bool (Bool(..))
8 import Data.Either (Either(..))
10 import Data.Maybe (Maybe(..))
11 import Data.Functor.Identity (Identity(..))
12 import Prelude (undefined)
13 import Text.Show (Show(..))
14 import qualified Data.Eq as Eq
15 import qualified Data.Function as Fun
16 import qualified Language.Haskell.TH as TH
17 import qualified Language.Haskell.TH.Syntax as TH
19 import qualified Symantic.Univariant.Trans as Sym
22 -- | Single-out some Haskell terms in order to
23 class Termable repr where
24 -- | Application, aka. unabstract.
25 (.@) :: repr (a->b) -> repr a -> repr b
26 -- | Lambda term abstraction, in HOAS (Higher-Order Abstract Syntax) style.
27 lam :: (repr a -> repr b) -> repr (a->b)
28 -- | Like 'lam' but whose argument is used only once,
29 -- hence safe to beta-reduce (inline) without duplicating work.
30 lam1 :: (repr a -> repr b) -> repr (a->b)
33 bool :: Bool -> repr Bool
34 char :: (TH.Lift tok, Show tok) => tok -> repr tok
35 cons :: repr (a -> [a] -> [a])
37 eq :: Eq a => repr (a -> a -> Bool)
39 left :: repr (l -> Either l r)
40 right :: repr (r -> Either l r)
41 nothing :: repr (Maybe a)
42 just :: repr (a -> Maybe a)
43 const :: repr (a -> b -> a)
44 flip :: repr ((a -> b -> c) -> b -> a -> c)
46 (.) :: repr ((b->c) -> (a->b) -> a -> c)
47 ($) :: repr ((a->b) -> a -> b)
50 Sym.Liftable2 repr => Termable (Sym.Output repr) =>
51 repr (a->b) -> repr a -> repr b
53 Sym.Liftable repr => Sym.Unliftable repr => Termable (Sym.Output repr) =>
54 (repr a -> repr b) -> repr (a->b)
56 Sym.Liftable repr => Sym.Unliftable repr => Termable (Sym.Output repr) =>
57 (repr a -> repr b) -> repr (a->b)
59 Sym.Liftable repr => Termable (Sym.Output repr) =>
62 Sym.Liftable repr => Termable (Sym.Output repr) =>
63 TH.Lift tok => Show tok =>
66 Sym.Liftable repr => Termable (Sym.Output repr) =>
67 repr (a -> [a] -> [a])
69 Sym.Liftable repr => Termable (Sym.Output repr) =>
72 Sym.Liftable repr => Termable (Sym.Output repr) =>
73 Eq a => repr (a -> a -> Bool)
75 Sym.Liftable repr => Termable (Sym.Output repr) =>
78 Sym.Liftable repr => Termable (Sym.Output repr) =>
79 repr (l -> Either l r)
81 Sym.Liftable repr => Termable (Sym.Output repr) =>
82 repr (r -> Either l r)
84 Sym.Liftable repr => Termable (Sym.Output repr) =>
87 Sym.Liftable repr => Termable (Sym.Output repr) =>
90 Sym.Liftable repr => Termable (Sym.Output repr) =>
93 Sym.Liftable repr => Termable (Sym.Output repr) =>
94 repr ((a -> b -> c) -> b -> a -> c)
96 Sym.Liftable repr => Termable (Sym.Output repr) =>
99 Sym.Liftable repr => Termable (Sym.Output repr) =>
100 repr ((b->c) -> (a->b) -> a -> c)
102 Sym.Liftable repr => Termable (Sym.Output repr) =>
103 repr ((a->b) -> a -> b)
105 (.@) = Sym.lift2 (.@)
106 lam f = Sym.lift (lam (Sym.trans Fun.. f Fun.. Sym.trans))
107 lam1 f = Sym.lift (lam1 (Sym.trans Fun.. f Fun.. Sym.trans))
108 bool = Sym.lift Fun.. bool
109 char = Sym.lift Fun.. char
115 right = Sym.lift right
116 nothing = Sym.lift nothing
118 const = Sym.lift const
127 -- * Type 'ValueCode'
128 data ValueCode a = ValueCode
132 instance Termable ValueCode where
134 { value = runIdentity (Identity (value f) .@ (Identity (value x)))
135 , code = code f .@ code x
138 { value = runIdentity (lam (Identity Fun.. value Fun.. f Fun.. (`ValueCode` undefined) Fun.. runIdentity))
139 , code = lam (code Fun.. f Fun.. ValueCode undefined)
142 bool b = ValueCode (runIdentity (bool b)) (bool b)
143 char c = ValueCode (runIdentity (char c)) (char c)
144 cons = ValueCode (runIdentity cons) cons
145 nil = ValueCode (runIdentity nil) nil
146 eq = ValueCode (runIdentity eq) eq
147 unit = ValueCode (runIdentity unit) unit
148 left = ValueCode (runIdentity left) left
149 right = ValueCode (runIdentity right) right
150 nothing = ValueCode (runIdentity nothing) nothing
151 just = ValueCode (runIdentity just) just
152 const = ValueCode (runIdentity const) const
153 flip = ValueCode (runIdentity flip) flip
154 id = ValueCode (runIdentity id) id
155 ($) = ValueCode (runIdentity ($)) ($)
156 (.) = ValueCode (runIdentity (.)) (.)
157 instance Termable Identity where
158 f .@ x = Identity (runIdentity f (runIdentity x))
159 lam f = Identity (runIdentity Fun.. f Fun.. Identity)
165 eq = Identity (Eq.==)
168 right = Identity Right
169 nothing = Identity Nothing
171 const = Identity Fun.const
172 flip = Identity Fun.flip
174 ($) = Identity (Fun.$)
175 (.) = Identity (Fun..)
176 instance Termable TH.CodeQ where
177 (.@) f x = [|| $$f $$x ||]
178 lam f = [|| \x -> $$(f [||x||]) ||]
187 right = [|| Right ||]
188 nothing = [|| Nothing ||]
190 const = [|| Fun.const ||]
192 flip = [|| \f x y -> f y x ||]
193 ($) = [|| (Fun.$) ||]
194 (.) = [|| (Fun..) ||]