1 {-# LANGUAGE ConstraintKinds #-}
3 {-# LANGUAGE DataKinds #-}
5 {-# LANGUAGE PatternSynonyms #-}
6 {-# LANGUAGE RankNTypes #-}
7 {-# LANGUAGE ViewPatterns #-}
9 module Symantic.Syntaxes.Data where
11 import Data.Bool (Bool)
12 import Data.Either (Either)
13 import Data.Eq qualified as Eq
14 import Data.Function qualified as Fun
15 import Data.Maybe (Maybe)
16 import Data.Maybe qualified as Maybe
17 import Data.Semigroup (Semigroup)
18 import Type.Reflection (Typeable, eqTypeRep, typeRep, (:~~:) (..))
20 import Symantic.Syntaxes.Classes
21 import Symantic.Syntaxes.Derive
26 ( Derivable (Data able sem)
29 SomeData (Data able sem a)
31 type instance Derived (SomeData sem) = sem
32 instance Derivable (SomeData sem) where
33 derive (SomeData x) = derive x
37 -- TODO: neither data families nor data instances
38 -- can have phantom roles with GHC-9's RoleAnnotations,
39 -- hence 'Data.Coerce.coerce' cannot be used on them for now.
40 -- https://gitlab.haskell.org/ghc/ghc/-/issues/8177
41 -- https://gitlab.haskell.org/ghc/ghc/-/wikis/roles#proposal-roles-for-type-families
42 data family Data (able :: Syntax) :: Semantic -> Semantic
43 type instance Derived (Data able sem) = sem
45 -- | Convenient utility to pattern-match a 'SomeData'.
46 pattern Data :: Typeable able => Data able sem a -> SomeData sem a
47 pattern Data x <- (unSomeData -> Maybe.Just x)
49 -- | @(unSomeData c :: 'Maybe' ('Data' able sem a))@
50 -- extract the data-constructor from the given 'SomeData'
51 -- iif. it belongs to the @('Data' able sem a)@ data-instance.
56 Maybe (Data able sem a)
57 unSomeData (SomeData (c :: Data c sem a)) =
58 case typeRep @able `eqTypeRep` typeRep @c of
59 Maybe.Just HRefl -> Maybe.Just c
60 Maybe.Nothing -> Maybe.Nothing
63 data instance Data Abstractable sem a where
64 Lam :: (SomeData sem a -> SomeData sem b) -> Data Abstractable sem (a -> b)
65 Lam1 :: (SomeData sem a -> SomeData sem b) -> Data Abstractable sem (a -> b)
66 Var :: sem a -> Data Abstractable sem a
67 instance Abstractable sem => Derivable (Data Abstractable sem) where
69 Lam f -> lam (\x -> derive (f (SomeData (Var x))))
70 Lam1 f -> lam1 (\x -> derive (f (SomeData (Var x))))
72 instance Abstractable sem => Abstractable (SomeData sem) where
73 lam f = SomeData (Lam f)
74 lam1 f = SomeData (Lam1 f)
77 -- | Beta-reduce the left-most outer-most lambda abstraction (aka. normal-order reduction),
78 -- but to avoid duplication of work, only those manually marked
79 -- as using their variable at most once.
81 -- DOC: Demonstrating Lambda Calculus Reduction, Peter Sestoft, 2001,
82 -- https://www.itu.dk/people/sestoft/papers/sestoft-lamreduce.pdf
83 normalOrderReduction ::
89 normalOrderReduction = nor
91 nor :: SomeData sem b -> SomeData sem b
93 Data (Lam f) -> lam (nor Fun.. f)
94 Data (Lam1 f) -> lam1 (nor Fun.. f)
95 Data (x :@ y) -> case whnf x of
96 Data (Lam1 f) -> nor (f y)
98 Data (IfThenElse test ok ko) ->
100 Data (Constant b :: Data (Constantable Bool) sem Bool) ->
101 if b then nor ok else nor ko
102 t -> ifThenElse (nor t) (nor ok) (nor ko)
105 whnf :: SomeData sem b -> SomeData sem b
107 Data (x :@ y) -> case whnf x of
108 Data (Lam1 f) -> whnf (f y)
113 data instance Data Unabstractable sem a where
114 (:@) :: SomeData sem (a -> b) -> SomeData sem a -> Data Unabstractable sem b
115 instance Unabstractable sem => Derivable (Data Unabstractable sem) where
117 f :@ x -> derive f .@ derive x
118 instance Unabstractable sem => Unabstractable (SomeData sem) where
119 f .@ x = SomeData (f :@ x)
125 Functionable (SomeData sem)
127 ($) = lam1 (\f -> lam1 (\x -> f .@ x))
128 (.) = lam1 (\f -> lam1 (\g -> lam1 (\x -> f .@ (g .@ x))))
129 const = lam1 (\x -> lam1 (\_y -> x))
130 flip = lam1 (\f -> lam1 (\x -> lam1 (\y -> f .@ y .@ x)))
134 data instance Data Anythingable sem a where
135 Anything :: sem a -> Data Anythingable sem a
139 Derivable (Data Anythingable sem)
142 Anything x -> anything x
143 instance Anythingable (SomeData sem)
144 instance Anythingable (Data Anythingable sem)
147 data instance Data Bottomable sem a where
148 Bottom :: Data Bottomable sem a
149 instance Bottomable sem => Derivable (Data Bottomable sem) where
150 derive Bottom{} = bottom
153 data instance Data (Constantable c) sem a where
154 Constant {-Typeable c =>-} :: c -> Data (Constantable c) sem c
155 instance Constantable c sem => Derivable (Data (Constantable c) sem) where
157 Constant x -> constant x
162 Constantable c (SomeData sem)
164 constant c = SomeData (Constant c)
165 instance{-Typeable c =>-} Constantable c (Data (Constantable c) sem) where
169 data instance Data Eitherable sem a where
170 Either :: Data Eitherable sem ((l -> a) -> (r -> a) -> Either l r -> a)
171 Left :: Data Eitherable sem (l -> Either l r)
172 Right :: Data Eitherable sem (r -> Either l r)
173 instance Eitherable sem => Derivable (Data Eitherable sem) where
178 instance Eitherable sem => Eitherable (SomeData sem) where
179 either = SomeData Either
181 right = SomeData Right
182 instance Eitherable (Data Eitherable sem) where
188 data instance Data Equalable sem a where
189 Equal :: Eq.Eq a => Data Equalable sem (a -> a -> Bool)
190 instance Equalable sem => Derivable (Data Equalable sem) where
196 Equalable (SomeData sem)
198 equal = SomeData Equal
199 instance Equalable (Data Equalable sem) where
203 data instance Data Emptyable sem a where
204 Empty :: Data Emptyable sem a
205 instance Emptyable sem => Derivable (Data Emptyable sem) where
211 Emptyable (SomeData sem)
213 empty = SomeData Empty
214 instance Emptyable (Data Emptyable sem) where
218 data instance Data Semigroupable sem a where
219 Concat :: Semigroup a => Data Semigroupable sem (a -> a -> a)
221 instance Semigroupable sem => Derivable (Data Semigroupable sem) where
227 Semigroupable (SomeData sem)
229 concat = SomeData Concat
230 instance Semigroupable (Data Semigroupable sem) where
234 data instance Data IfThenElseable sem a where
239 Data IfThenElseable sem a
240 instance IfThenElseable sem => Derivable (Data IfThenElseable sem) where
242 IfThenElse test ok ko -> ifThenElse (derive test) (derive ok) (derive ko)
246 IfThenElseable (SomeData sem)
248 ifThenElse test ok ko = SomeData (IfThenElse test ok ko)
249 instance IfThenElseable sem => IfThenElseable (Data IfThenElseable sem) where
250 ifThenElse test ok ko = IfThenElse (SomeData test) (SomeData ok) (SomeData ko)
253 data instance Data Listable sem a where
254 Cons :: Data Listable sem (a -> [a] -> [a])
255 Nil :: Data Listable sem [a]
257 instance Listable sem => Derivable (Data Listable sem) where
264 Listable (SomeData sem)
268 instance Listable (Data Listable sem) where
273 data instance Data Maybeable sem a where
274 Nothing :: Data Maybeable sem (Maybe a)
275 Just :: Data Maybeable sem (a -> Maybe a)
276 instance Maybeable sem => Derivable (Data Maybeable sem) where
283 Maybeable (SomeData sem)
285 nothing = SomeData Nothing
287 instance Maybeable (Data Maybeable sem) where