1 {-# LANGUAGE ConstraintKinds #-} -- For type class synonyms
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE DefaultSignatures #-} -- For adding Trans* constraints
4 module Symantic.Univariant.Trans where
6 -- TODO: move to symantic-univariant
8 import Data.Function ((.))
9 import Data.Kind (Type)
11 -- * Type family 'Output'
12 type family Output (repr :: Type -> Type) :: Type -> Type
15 -- | A 'trans'formation from an interpreter @(from)@ to an interpreter @(to)@.
16 class Trans from to where
17 trans :: from a -> to a
18 class MetaTrans some from to where
19 meta :: some from a -> some to a
21 newtype Compo some repr a = Compo { getCompo :: some repr a }
22 type family UnSome s where
27 -- | Convenient type class synonym.
28 -- Note that this is not necessarily a bijective 'trans'lation,
29 -- a 'trans' being not necessarily injective nor surjective.
30 type BiTrans from to = (Trans from to, Trans to from)
32 -- ** Class 'Liftable'
33 -- | Convenient type class synonym for using 'Output'
34 type Liftable repr = Trans (Output repr) repr
35 lift :: forall repr a.
37 Output repr a -> repr a
38 lift = trans @(Output repr)
41 unlift :: forall repr a.
42 Trans repr (Output repr) =>
43 repr a -> Output repr a
47 -- ** Class 'Unliftable'
48 -- | Convenient type class synonym for using 'Output'
49 type Unliftable repr = Trans repr (Output repr)
52 class Trans1 from to where
60 trans1 f = trans . f . trans
63 -- ** Class 'Liftable1'
64 -- | Convenient type class synonym for using 'Output'
65 type Liftable1 repr = Trans1 (Output repr) repr
66 lift1 :: forall repr a b.
68 (Output repr a -> Output repr b) ->
70 lift1 = trans1 @(Output repr)
74 class Trans2 from to where
76 (from a -> from b -> from c) ->
80 (from a -> from b -> from c) ->
82 trans2 f a b = trans (f (trans a) (trans b))
85 -- ** Class 'Liftable2'
86 -- | Convenient type class synonym for using 'Output'
87 type Liftable2 repr = Trans2 (Output repr) repr
88 lift2 :: forall repr a b c.
90 (Output repr a -> Output repr b -> Output repr c) ->
91 repr a -> repr b -> repr c
92 lift2 = trans2 @(Output repr)
96 class Trans3 from to where
98 (from a -> from b -> from c -> from d) ->
99 to a -> to b -> to c -> to d
102 (from a -> from b -> from c -> from d) ->
103 to a -> to b -> to c -> to d
104 trans3 f a b c = trans (f (trans a) (trans b) (trans c))
105 {-# INLINE trans3 #-}
107 -- ** Class 'Liftable3'
108 -- | Convenient type class synonym for using 'Output'
109 type Liftable3 repr = Trans3 (Output repr) repr
110 lift3 :: forall repr a b c d.
112 (Output repr a -> Output repr b -> Output repr c -> Output repr d) ->
113 repr a -> repr b -> repr c -> repr d
114 lift3 = trans3 @(Output repr)
119 -- | A newtype to disambiguate the 'Trans' instance to any other interpreter when there is also one or more 'Trans's to other interpreters with a different interpretation than the generic one.
120 newtype Any repr a = Any { unAny :: repr a }
121 type instance Output (Any repr) = repr
122 instance Trans (Any repr) repr where
124 instance Trans1 (Any repr) repr
125 instance Trans2 (Any repr) repr
126 instance Trans3 (Any repr) repr
127 instance Trans repr (Any repr) where
129 instance Trans1 repr (Any repr)
130 instance Trans2 repr (Any repr)
131 instance Trans3 repr (Any repr)