1 {-# LANGUAGE NoMonomorphismRestriction #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 {-# LANGUAGE ViewPatterns #-}
4 module Symantic.Parser.Haskell.Optimize where
6 import Data.Bool (Bool(..))
7 import Data.Functor.Identity (Identity(..))
8 import Data.String (String)
9 import Prelude (undefined)
10 import Text.Show (Show(..))
11 import qualified Data.Eq as Eq
12 import qualified Data.Function as Fun
13 import qualified Language.Haskell.TH as TH
14 import qualified Language.Haskell.TH.Syntax as TH
16 import Symantic.Univariant.Trans
17 import Symantic.Parser.Haskell.Term
20 -- | Initial encoding of some 'Termable' symantics,
21 -- useful for some optimizations in 'optimizeTerm'.
22 data Term repr a where
23 -- | Black-box for all terms neither interpreted nor pattern-matched.
24 Term :: { unTerm :: repr a } -> Term repr a
26 -- Terms useful for 'optimizeTerm'.
27 (:@) :: Term repr (a->b) -> Term repr a -> Term repr b
28 Lam :: (Term repr a -> Term repr b) -> Term repr (a->b)
29 Lam1 :: (Term repr a -> Term repr b) -> Term repr (a->b)
30 Var :: String -> Term repr a
32 -- Terms useful for prettier dumps.
33 Char :: (TH.Lift tok, Show tok) => tok -> Term repr tok
34 Cons :: Term repr (a -> [a] -> [a])
35 Eq :: Eq.Eq a => Term repr (a -> a -> Bool)
37 Const :: Term repr (a -> b -> a)
38 Flip :: Term repr ((a -> b -> c) -> b -> a -> c)
39 Id :: Term repr (a->a)
40 (:$) :: Term repr ((a->b) -> a -> b)
41 -- (:.) :: Term repr ((b->c) -> (a->b) -> a -> c)
47 type instance Output (Term repr) = repr
48 instance Trans repr (Term repr) where
51 instance Termable repr => Termable (Term repr) where
58 bool b = Term (bool b)
63 nothing = Term nothing
65 const = Lam1 (\x -> Lam1 (\_y -> x))
66 flip = Lam1 (\f -> Lam1 (\x -> Lam1 (\y -> f .@ y .@ x)))
68 ($) = Lam1 (\f -> Lam1 (\x -> f .@ x))
69 (.) = Lam1 (\f -> Lam1 (\g -> Lam1 (\x -> f .@ (g .@ x))))
71 -- | Beta-reduce the left-most outer-most lambda abstraction (aka. normal-order reduction),
72 -- but to avoid duplication of work, only those manually marked
73 -- as using their variable at most once.
74 -- This is mainly to get prettier splices.
76 -- DOC: Demonstrating Lambda Calculus Reduction, Peter Sestoft, 2001,
77 -- https://www.itu.dk/people/sestoft/papers/sestoft-lamreduce.pdf
78 optimizeTerm :: Term repr a -> Term repr a
81 -- | normal-order reduction
82 nor :: Term repr a -> Term repr a
84 Lam f -> Lam (nor Fun.. f)
85 Lam1 f -> Lam1 (nor Fun.. f)
86 x :@ y -> case whnf x of
90 -- | weak-head normal-form
91 whnf :: Term repr a -> Term repr a
93 x :@ y -> case whnf x of
98 instance Trans (Term Identity) Identity where
104 x :@ y -> Identity (runIdentity (trans x) (runIdentity (trans y)))
105 Lam f -> Identity (runIdentity Fun.. trans Fun.. f Fun.. Term Fun.. Identity)
106 Lam1 f -> trans (Lam f)
114 instance Trans (Term TH.CodeQ) TH.CodeQ where
115 -- Superfluous pattern-matches are only here
116 -- for cosmetic concerns when reading *.dump-splices,
117 -- not for optimizing, which is done in 'optimizeTerm'.
119 Cons :@ x :@ y -> [|| $$(trans x) : $$(trans y) ||]
120 Cons :@ x -> [|| ($$(trans x) :) ||]
123 Eq :@ x :@ y -> [|| $$(trans x) Eq.== $$(trans y) ||]
124 Eq :@ x -> [|| ($$(trans x) Eq.==) ||]
127 -- (:$) :@ x -> [|| ($$(trans x) Fun.$) ||]
128 -- (:.) :@ f :@ g -> [|| \xx -> $$(trans f) ($$(trans g) xx) ||]
129 -- (:.) :@ (:.) -> [|| \f x -> (\g y -> (f x) (g y)) ||]
130 -- (:.) :@ x :@ y -> [|| $$(trans x) Fun.. $$(trans y) ||]
131 -- (:.) :@ x -> [|| ($$(trans x) Fun..) ||]
132 -- (:.) :@ f -> [|| \g x -> $$(trans f) (g x) ||]
134 x :@ y -> [|| $$(trans x) $$(trans y) ||]
135 Lam f -> [|| \x -> $$(trans (f (Term [||x||]))) ||]
136 Lam1 f -> trans (Lam f)
144 instance Trans (Term ValueCode) ValueCode where
150 (:@) f x -> (.@) (trans f) (trans x)
152 { value = value Fun.. trans Fun.. f Fun.. Term Fun.. (`ValueCode` undefined)
153 , code = [|| \x -> $$(code Fun.. trans Fun.. f Fun.. Term Fun.. (undefined `ValueCode`) Fun.$ [||x||]) ||]
155 Lam1 f -> trans (Lam f)
163 instance Trans (Term ValueCode) (Term TH.CodeQ) where
165 Term x -> Term (code x)
169 (:@) f x -> (.@) (trans f) (trans x)
170 Lam f -> Lam (\x -> trans (f (trans x)))
171 Lam1 f -> Lam1 (\x -> trans (f (trans x)))
179 instance Trans (Term TH.CodeQ) (Term ValueCode) where
181 Term x -> Term (ValueCode undefined x)
185 (:@) f x -> (.@) (trans f) (trans x)
186 Lam f -> Lam (\x -> trans (f (trans x)))
187 Lam1 f -> Lam1 (\x -> trans (f (trans x)))