-
Notifications
You must be signed in to change notification settings - Fork 42
/
Monotonic.hs
90 lines (64 loc) · 2.8 KB
/
Monotonic.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
module SubHask.Category.Trans.Monotonic
( Mon
, unsafeProveMon
-- * The MonT transformer
, MonT (..)
, unsafeProveMonT
)
where
import SubHask.Category
import SubHask.Algebra
import SubHask.SubType
data IncreasingT cat (a :: *) (b :: *) where
IncreasingT :: (Ord_ a, Ord_ b) => cat a b -> IncreasingT cat a b
mkMutable [t| forall cat a b. IncreasingT cat a b |]
instance Category cat => Category (IncreasingT cat) where
type ValidCategory (IncreasingT cat) a = (ValidCategory cat a, Ord_ a)
id = IncreasingT id
(IncreasingT f).(IncreasingT g) = IncreasingT $ f.g
instance Sup a b c => Sup (IncreasingT a) b c
instance Sup b a c => Sup a (IncreasingT b) c
instance (subcat <: cat) => IncreasingT subcat <: cat where
embedType_ = Embed2 (\ (IncreasingT f) -> embedType2 f)
instance Semigroup (cat a b) => Semigroup (IncreasingT cat a b) where
(IncreasingT f)+(IncreasingT g) = IncreasingT $ f+g
instance Abelian (cat a b) => Abelian (IncreasingT cat a b) where
instance Provable (IncreasingT Hask) where
f $$ a = ProofOf $ (f $ unProofOf a)
newtype instance ProofOf (IncreasingT cat) a = ProofOf { unProofOf :: ProofOf_ cat a }
mkMutable [t| forall a cat. ProofOf (IncreasingT cat) a |]
instance Semigroup (ProofOf_ cat a) => Semigroup (ProofOf (IncreasingT cat) a) where
(ProofOf a1)+(ProofOf a2) = ProofOf (a1+a2)
instance Abelian (ProofOf_ cat a) => Abelian (ProofOf (IncreasingT cat) a)
type Increasing a = Increasing_ a
type family Increasing_ a where
Increasing_ ( (cat :: * -> * -> *) a b) = IncreasingT cat a b
proveIncreasing ::
( Ord_ a
, Ord_ b
) => (ProofOf (IncreasingT Hask) a -> ProofOf (IncreasingT Hask) b) -> Increasing (a -> b)
proveIncreasing f = unsafeProveIncreasing $ \a -> unProofOf $ f $ ProofOf a
instance (Ord_ a, Ord_ b) => Hask (ProofOf (IncreasingT Hask) a) (ProofOf (IncreasingT Hask) b) <: (IncreasingT Hask) a b where
embedType_ = Embed0 proveIncreasing
unsafeProveIncreasing ::
( Ord_ a
, Ord_ b
) => (a -> b) -> Increasing (a -> b)
unsafeProveIncreasing = IncreasingT
-- | A convenient specialization of "MonT" and "Hask"
type Mon = MonT Hask
type ValidMon a = Ord a
data MonT cat (a :: *) (b :: *) where
MonT :: (ValidMon a, ValidMon b) => cat a b -> MonT cat a b
unsafeProveMonT :: (ValidMon a, ValidMon b) => cat a b -> MonT cat a b
unsafeProveMonT = MonT
unsafeProveMon :: (ValidMon a, ValidMon b) => cat a b -> MonT cat a b
unsafeProveMon = MonT
instance Category cat => Category (MonT cat) where
type ValidCategory (MonT cat) a = (ValidCategory cat a, ValidMon a)
id = MonT id
(MonT f).(MonT g) = MonT $ f.g
instance Sup a b c => Sup (MonT a) b c
instance Sup b a c => Sup a (MonT b) c
instance (subcat <: cat) => MonT subcat <: cat where
embedType_ = Embed2 (\ (MonT f) -> embedType2 f)