1 {-# LANGUAGE TypeFamilyDependencies #-} -- For Permutation
2 {-# LANGUAGE UndecidableInstances #-} -- For Permutation
3 module Symantic.Dityped.Lang where
5 import Data.Either (Either)
7 import Data.Function ((.))
8 import Data.Maybe (Maybe(..), fromJust)
9 import Data.Proxy (Proxy(..))
10 import GHC.Generics (Generic)
11 import Text.Show (Show)
13 import Symantic.Dityped.ADT
14 import Symantic.Dityped.CurryN
15 import Symantic.Dityped.Derive
17 -- * Class 'Composable'
18 class Composable repr where
19 (<.>) :: repr a b -> repr b c -> repr a c
20 (<.>) = liftDerived2 (<.>)
22 FromDerived2 Composable repr =>
23 repr a b -> repr b c -> repr a c
26 -- ** Class 'Constant'
27 class Constant repr where
28 constant :: a -> repr (a -> k) k
29 constant = liftDerived . constant
31 FromDerived Constant repr =>
34 -- * Class 'Dicurryable'
35 class Dicurryable repr where
39 (args-..->r) -> -- construction
40 (r->Tuples args) -> -- destruction
41 repr (args-..->k) k ->
43 dicurry args constr destr = liftDerived1 (dicurry args constr destr)
45 FromDerived1 Dicurryable repr =>
50 repr (args-..->k) k ->
59 Tuples args ~ EoT (ADT a) =>
60 (args ~ Args (args-..->a)) =>
62 repr (args-..->k) k ->
64 construct f = dicurry (Proxy::Proxy args) f eotOfadt
66 -- * Class 'Dimapable'
67 class Dimapable repr where
68 dimap :: (a->b) -> (b->a) -> repr (a->k) k -> repr (b->k) k
69 dimap a2b b2a = liftDerived1 (dimap a2b b2a)
71 FromDerived1 Dimapable repr =>
72 (a->b) -> (b->a) -> repr (a->k) k -> repr (b->k) k
74 -- * Class 'Eitherable'
75 class Eitherable repr where
76 (<+>) :: repr (a->k) k -> repr (b->k) k -> repr (Either a b->k) k
77 (<+>) = liftDerived2 (<+>)
79 FromDerived2 Eitherable repr =>
80 repr (a->k) k -> repr (b->k) k -> repr (Either a b -> k) k
81 -- NOTE: yes infixr, not infixl like <|>,
82 -- in order to run left-most checks first.
85 -- | @('adt' @@SomeADT some_expr)@
86 -- wrap\/unwrap @(some_expr)@ input\/output value
87 -- to\/from the Algebraic Data Type @(SomeADT)@.
88 -- @(SomeADT)@ must have a 'Generic' instance
89 -- (using the @DeriveGeneric@ language extension to GHC).
96 repr (EoT (ADT adt) -> k) k ->
98 adt = dimap adtOfeot eotOfadt
100 -- ** Class 'Emptyable'
101 class Emptyable repr where
103 empty = liftDerived empty
105 FromDerived Emptyable repr =>
108 -- ** Class 'Optionable'
109 class Optionable repr where
110 option :: repr k k -> repr k k
111 optional :: repr (a->k) k -> repr (Maybe a->k) k
112 option = liftDerived1 option
113 optional = liftDerived1 optional
115 FromDerived1 Optionable repr =>
118 FromDerived1 Optionable repr =>
119 repr (a->k) k -> repr (Maybe a->k) k
121 -- * Class 'Permutable'
122 class Permutable repr where
123 -- Use @TypeFamilyDependencies@ to help type-inference infer @(repr)@.
124 type Permutation (repr:: * -> * -> *) = (r :: * -> * -> *) | r -> repr
125 type Permutation repr = Permutation (Derived repr)
126 permutable :: Permutation repr (a->k) k -> repr (a->k) k
127 perm :: repr (a->k) k -> Permutation repr (a->k) k
128 noPerm :: Permutation repr k k
129 permWithDefault :: a -> repr (a->k) k -> Permutation repr (a->k) k
131 Eitherable repr => Dimapable repr => Permutable repr =>
132 repr (a->k) k -> Permutation repr (Maybe a -> k) k
133 optionalPerm = permWithDefault Nothing . dimap Just fromJust
137 Tupable (Permutation repr) =>
139 Permutation repr (b->k) k ->
140 Permutation repr ((a,b)->k) k
141 x <&> y = perm x <:> y
147 Tupable (Permutation repr) =>
149 Permutation repr (b->k) k ->
150 Permutation repr ((Maybe a,b)->k) k
151 x <?&> y = optionalPerm x <:> y
158 Tupable (Permutation repr) =>
160 Permutation repr (b->k) k ->
161 Permutation repr (([a],b)->k) k
162 x <*&> y = permWithDefault [] (many1 x) <:> y
169 Tupable (Permutation repr) =>
171 Permutation repr (b->k) k ->
172 Permutation repr (([a],b)->k) k
173 x <+&> y = perm (many1 x) <:> y
181 {-# INLINE (<?&>) #-}
182 {-# INLINE (<*&>) #-}
183 {-# INLINE (<+&>) #-}
185 -- * Class 'Repeatable'
186 class Repeatable repr where
187 many0 :: repr (a->k) k -> repr ([a]->k) k
188 many1 :: repr (a->k) k -> repr ([a]->k) k
189 many0 = liftDerived1 many0
190 many1 = liftDerived1 many1
192 FromDerived1 Repeatable repr =>
193 repr (a->k) k -> repr ([a]->k) k
195 FromDerived1 Repeatable repr =>
196 repr (a->k) k -> repr ([a]->k) k
198 -- * Class 'Routable'
199 class Routable repr where
200 (<!>) :: repr a k -> repr b k -> repr (a:!:b) k
201 (<!>) = liftDerived2 (<!>)
203 FromDerived2 Routable repr =>
204 repr a k -> repr b k -> repr (a:!:b) k
208 -- | Like @(,)@ but @infixr@.
209 -- Mostly useful for clarity when using 'Routable'.
210 data (:!:) a b = a:!:b
214 -- * Class 'Substractable'
215 class Substractable repr where
216 (<->) :: repr a k -> repr k' k' -> repr a k
217 (<->) = liftDerived2 (<->)
219 FromDerived2 Substractable repr =>
220 repr a k -> repr k' k' -> repr a k
224 class Tupable repr where
225 (<:>) :: repr (a->k) k -> repr (b->k) k -> repr ((a,b)->k) k
226 (<:>) = liftDerived2 (<:>)
228 FromDerived2 Tupable repr =>
229 repr (a->k) k -> repr (b->k) k -> repr ((a,b)->k) k
232 -- ** Class 'Unitable'
233 class Unitable repr where
234 unit :: repr (() -> k) k
235 unit = liftDerived unit
237 FromDerived Unitable repr =>
240 -- * Class 'Voidable'
241 class Voidable repr where
243 FromDerived1 Voidable repr =>
244 a -> repr (a -> b) k -> repr b k
245 void :: a -> repr (a -> b) k -> repr b k
246 void a = liftDerived1 (void a)