1 {-# LANGUAGE MultiParamTypeClasses #-}
2 module Language.LOL.Symantic.Trans.Common where
5 -- * 'trans_lift' is generally not /surjective/
6 -- * 'trans_apply' is not /injective/
7 -- * 'trans_apply' . 'trans_lift' == 'id'
8 -- * 'trans_lift' . 'trans_apply' /= 'id'
10 -- NOTE: @DefaultSignatures@ can be used
11 -- when declaring a symantic type class
12 -- to provide default definition of the methods
13 -- implementing their identity transformation
14 -- in order to avoid boilerplate code
15 -- when writting 'Trans' instances which
16 -- do not need to alterate those methods.
17 class Trans trans repr where
18 -- | Lift an interpreter to the transformer's.
19 trans_lift :: repr a -> trans repr a
20 -- | Unlift an interpreter from the transformer's.
21 trans_apply :: trans repr a -> repr a
23 -- | Convenient method to define the identity transformation for a unary symantic method.
24 trans_map1 :: (repr a -> repr b) -> (trans repr a -> trans repr b)
25 trans_map1 f = trans_lift . f . trans_apply
27 -- | Convenient method to define the identity transformation for a binary symantic method.
29 :: (repr a -> repr b -> repr c)
30 -> (trans repr a -> trans repr b -> trans repr c)
31 trans_map2 f e1 e2 = trans_lift (trans_apply e1 `f` trans_apply e2)
33 -- | Convenient method to define the identity transformation for a terary symantic method.
35 :: (repr a -> repr b -> repr c -> repr d)
36 -> (trans repr a -> trans repr b -> trans repr c -> trans repr d)
37 trans_map3 f e1 e2 e3 = trans_lift $ f (trans_apply e1) (trans_apply e2) (trans_apply e3)