1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE DataKinds #-}
3 {-# LANGUAGE FlexibleContexts #-}
4 {-# LANGUAGE FlexibleInstances #-}
6 {-# LANGUAGE KindSignatures #-}
7 {-# LANGUAGE LambdaCase #-}
8 {-# LANGUAGE MultiParamTypeClasses #-}
9 {-# LANGUAGE PatternSynonyms #-}
10 {-# LANGUAGE RankNTypes #-}
11 {-# LANGUAGE ScopedTypeVariables #-}
12 {-# LANGUAGE StandaloneDeriving #-}
13 {-# LANGUAGE TypeApplications #-}
14 {-# LANGUAGE TypeFamilies #-}
15 {-# LANGUAGE ViewPatterns #-}
16 module Symantic.Typed.Data where
18 import Data.Kind (Constraint, Type)
19 import Type.Reflection (Typeable, (:~~:)(..), eqTypeRep, typeRep)
20 import Data.Bool (Bool)
21 import Data.Either (Either)
22 import Data.Maybe (Maybe)
23 import qualified Data.Eq as Eq
24 import qualified Data.Maybe as Maybe
25 import qualified Data.Function as Fun
27 import Symantic.Typed.Lang
28 import Symantic.Typed.Trans
30 data SomeData repr a =
32 ( Trans (Data able repr) repr
34 ) => SomeData (Data able repr a)
36 instance Trans (SomeData repr) repr where
37 trans (SomeData x) = trans x
39 type TypedRepr = Type -> Type
41 -- TODO: neither data families nor data instances
42 -- can have phantom roles with GHC-9's RoleAnnotations,
43 -- hence 'Data.Coerce.coerce' cannot be used on them for now.
44 -- https://gitlab.haskell.org/ghc/ghc/-/issues/8177
45 -- https://gitlab.haskell.org/ghc/ghc/-/wikis/roles#proposal-roles-for-type-families
46 -- Would be useful for @Trans (Data able repr) (Data able repr')@ instances.
48 (able :: TypedRepr -> Constraint)
49 :: TypedRepr -> TypedRepr
50 --instance Trans (Data able repr) (Data able repr) where
53 -- | Convenient utility to pattern-match a 'SomeData'.
54 pattern Data :: Typeable able => Data able repr a -> SomeData repr a
55 pattern Data x <- (unSomeData -> Maybe.Just x)
57 -- | @(unSomeData c :: 'Maybe' ('Data' able repr a))@
58 -- extract the data-constructor from the given 'SomeData'
59 -- iif. it belongs to the @('Data' able repr a)@ data-instance.
63 SomeData repr a -> Maybe (Data able repr a)
64 unSomeData (SomeData (c::Data c repr a)) =
65 case typeRep @able `eqTypeRep` typeRep @c of
66 Maybe.Just HRefl -> Maybe.Just c
67 Maybe.Nothing -> Maybe.Nothing
70 data instance Data Abstractable repr a where
71 (:@) :: SomeData repr (a->b) -> SomeData repr a -> Data Abstractable repr b
72 Lam :: (SomeData repr a -> SomeData repr b) -> Data Abstractable repr (a->b)
73 Lam1 :: (SomeData repr a -> SomeData repr b) -> Data Abstractable repr (a->b)
74 Var :: repr a -> Data Abstractable repr a
75 -- FIXME: add constructors
78 --, Trans (SomeData repr) repr
79 --, Trans repr (SomeData repr)
80 ) => Trans (Data Abstractable repr) repr where
82 f :@ x -> trans f .@ trans x
83 Lam f -> lam (\x -> trans (f (SomeData (Var x))))
84 Lam1 f -> lam1 (\x -> trans (f (SomeData (Var x))))
88 --, Trans (SomeData repr) repr
89 --, Trans repr (SomeData repr)
90 ) => Abstractable (SomeData repr) where
91 f .@ x = SomeData (f :@ x)
92 lam f = SomeData (Lam f)
93 lam1 f = SomeData (Lam1 f)
95 ($) = lam1 (\f -> lam1 (\x -> f .@ x))
96 (.) = lam1 (\f -> lam1 (\g -> lam1 (\x -> f .@ (g .@ x))))
97 const = lam1 (\x -> lam1 (\_y -> x))
98 flip = lam1 (\f -> lam1 (\x -> lam1 (\y -> f .@ y .@ x)))
105 Abstractable (Data Abstractable repr) where
106 var = Var Fun.. SomeData
107 f .@ x = SomeData f :@ SomeData x
108 lam f = Lam (SomeData Fun.. f Fun.. Var)
109 lam1 f = Lam1 (SomeData Fun.. f Fun.. Var)
110 ($) = lam1 (\f -> lam1 (\x -> f .@ x))
111 (.) = lam1 (\f -> lam1 (\g -> lam1 (\x -> f .@ (g .@ x))))
112 const = lam1 (\x -> lam1 (\_y -> x))
113 flip = lam1 (\f -> lam1 (\x -> lam1 (\y -> f .@ y .@ x)))
117 instance Bottomable repr => Morph (SomeData repr) (SomeData Unit) where
118 morph (SomeData x) = morph x
119 instance Bottomable repr => Morph (SomeData Unit) (SomeData repr) where
120 morph (SomeData x) = morph x
121 instance Abstractable Unit where
130 instance Abstractable (Data Abstractable Unit) where
131 f .@ x = SomeData f :@ SomeData x
132 lam f = Lam (\(SomeData x) -> SomeData (f (trans x)))
133 lam1 f = Lam1 (\(SomeData x) -> SomeData (f (trans x)))
142 data instance Data Anythingable repr a where
143 Anything :: repr a -> Data Anythingable repr a
147 Trans (Data Anythingable repr) repr where
149 Anything x -> anything x
150 instance Anythingable (SomeData repr)
151 instance Anythingable (Data Anythingable repr)
154 class Bottomable repr where
156 data instance Data Bottomable repr a where
157 Bottom :: Data Bottomable repr a
158 instance Bottomable repr => Trans (Data Bottomable repr) repr where
159 trans Bottom{} = bottom
162 data instance Data (Constantable c) repr a where
163 Constant :: {-Typeable c =>-} c -> Data (Constantable c) repr c
164 instance Constantable c repr => Trans (Data (Constantable c) repr) repr where
166 Constant x -> constant x
168 ( Constantable c repr
170 ) => Constantable c (SomeData repr) where
171 constant c = SomeData (Constant c)
172 instance {-Typeable c =>-} Constantable c (Data (Constantable c) repr) where
176 data instance Data Eitherable repr a where
177 Left :: Data Eitherable repr (l -> Either l r)
178 Right :: Data Eitherable repr (r -> Either l r)
179 instance Eitherable repr => Trans (Data Eitherable repr) repr where
185 ) => Eitherable (SomeData repr) where
187 right = SomeData Right
188 instance Eitherable (Data Eitherable repr) where
193 data instance Data Equalable repr a where
194 Equal :: Eq.Eq a => Data Equalable repr (a -> a -> Bool)
195 instance Equalable repr => Trans (Data Equalable repr) repr where
200 ) => Equalable (SomeData repr) where
201 equal = SomeData Equal
202 instance Equalable (Data Equalable repr) where
206 data instance Data IfThenElseable repr a where
208 SomeData repr Bool ->
211 Data IfThenElseable repr a
212 instance IfThenElseable repr => Trans (Data IfThenElseable repr) repr where
214 IfThenElse test ok ko -> ifThenElse (trans test) (trans ok) (trans ko)
216 ( IfThenElseable repr
217 ) => IfThenElseable (SomeData repr) where
218 ifThenElse test ok ko = SomeData (IfThenElse test ok ko)
219 instance IfThenElseable repr => IfThenElseable (Data IfThenElseable repr) where
220 ifThenElse test ok ko = IfThenElse (SomeData test) (SomeData ok) (SomeData ko)
223 data instance Data Listable repr a where
224 Cons :: Data Listable repr (a -> [a] -> [a])
225 Nil :: Data Listable repr [a]
227 instance Listable repr => Trans (Data Listable repr) repr where
233 ) => Listable (SomeData repr) where
236 instance Listable (Data Listable repr) where
241 data instance Data Maybeable repr a where
242 Nothing :: Data Maybeable repr (Maybe a)
243 Just :: Data Maybeable repr (a -> Maybe a)
244 instance Maybeable repr => Trans (Data Maybeable repr) repr where
250 ) => Maybeable (SomeData repr) where
251 nothing = SomeData Nothing
253 instance Maybeable (Data Maybeable repr) where