1 {-# LANGUAGE ConstraintKinds #-} -- For type class synonyms
2 {-# LANGUAGE PolyKinds #-}
3 {-# LANGUAGE DefaultSignatures #-} -- For adding Trans constraints
4 module Symantic.Typed.Trans where
6 import Data.Function ((.))
7 import Data.Kind (Type)
9 -- * Type family 'Unlifted'
10 type family Unlifted (repr :: Type -> Type) :: Type -> Type
13 -- | A 'trans'formation from an interpreter @(from)@ to an interpreter @(to)@.
14 class Trans from to where
15 trans :: from a -> to a
18 -- | Convenient type class synonym.
19 -- Note that this is not necessarily a bijective 'trans'lation,
20 -- a 'trans' being not necessarily injective nor surjective.
21 type BiTrans from to = (Trans from to, Trans to from)
23 -- ** Class 'Liftable'
24 -- | Convenient type class synonym for using 'Unlifted'
25 type Liftable repr = Trans (Unlifted repr) repr
26 lift :: forall repr a.
28 Unlifted repr a -> repr a
29 lift = trans @(Unlifted repr)
32 unlift :: forall repr a.
33 Trans repr (Unlifted repr) =>
34 repr a -> Unlifted repr a
38 -- ** Class 'Unliftable'
39 -- | Convenient type class synonym for using 'Unlifted'
40 type Unliftable repr = Trans repr (Unlifted repr)
43 class Trans1 from to where
51 trans1 f = trans . f . trans
54 -- ** Class 'Liftable1'
55 -- | Convenient type class synonym for using 'Unlifted'
56 type Liftable1 repr = Trans1 (Unlifted repr) repr
57 lift1 :: forall repr a b.
59 (Unlifted repr a -> Unlifted repr b) ->
61 lift1 = trans1 @(Unlifted repr)
65 class Trans2 from to where
67 (from a -> from b -> from c) ->
71 (from a -> from b -> from c) ->
73 trans2 f a b = trans (f (trans a) (trans b))
76 -- ** Class 'Liftable2'
77 -- | Convenient type class synonym for using 'Unlifted'
78 type Liftable2 repr = Trans2 (Unlifted repr) repr
79 lift2 :: forall repr a b c.
81 (Unlifted repr a -> Unlifted repr b -> Unlifted repr c) ->
82 repr a -> repr b -> repr c
83 lift2 = trans2 @(Unlifted repr)
87 class Trans3 from to where
89 (from a -> from b -> from c -> from d) ->
90 to a -> to b -> to c -> to d
93 (from a -> from b -> from c -> from d) ->
94 to a -> to b -> to c -> to d
95 trans3 f a b c = trans (f (trans a) (trans b) (trans c))
98 -- ** Class 'Liftable3'
99 -- | Convenient type class synonym for using 'Unlifted'
100 type Liftable3 repr = Trans3 (Unlifted repr) repr
101 lift3 :: forall repr a b c d.
103 (Unlifted repr a -> Unlifted repr b -> Unlifted repr c -> Unlifted repr d) ->
104 repr a -> repr b -> repr c -> repr d
105 lift3 = trans3 @(Unlifted repr)
110 -- | 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.
111 newtype Any repr a = Any { unAny :: repr a }
112 type instance Unlifted (Any repr) = repr
113 instance Trans (Any repr) repr where
115 instance Trans1 (Any repr) repr
116 instance Trans2 (Any repr) repr
117 instance Trans3 (Any repr) repr
118 instance Trans repr (Any repr) where
120 instance Trans1 repr (Any repr)
121 instance Trans2 repr (Any repr)
122 instance Trans3 repr (Any repr)