1use std::marker::PhantomData;
2use crate::*;
3
4pub trait Monad: Type {
5 type Wrapped: Type;
6 type HKT<A: Type>: Type + Monad<Wrapped=A>;
7}
8
9pub type Return<M, V> = Eval<Pure<M>, V>;
10
11#[derive(Copy, Clone, Default)]
12pub struct Pure<M: Monad>(PhantomData<M>);
13
14impl<
15 MT: Monad,
16> Value for Pure<MT> {
17 type Type = Lambda<MT::Wrapped, MT>;
18}
19
20pub type Bind<M, F> = Eval<BindOn<<M as Value>::Type, F>, M>;
21#[derive(Copy, Clone, Default)]
22pub struct BindOn<M: Monad, F: Value>(PhantomData<(M, F)>);
23
24impl<
25 A: Type, B: Type,
26 MB: Type + Monad<Wrapped=B>,
27 M: Monad<Wrapped=A, HKT<B> =MB>,
28 F: Value<Type=Lambda<A, MB>>
29> Value for BindOn<M, F>{
30 type Type = Lambda<M, MB>;
31}