ty_ops/
list.rs

1use std::marker::PhantomData;
2
3use crate::*;
4use crate::classes::*;
5
6pub type List1<I> = Segment<I, Empty<<I as Value>::Type>>;
7pub type List2<I1, I2> = Push<I2, List1<I1>>;
8pub type List3<I1, I2, I3> = Push<I3, List2<I1, I2>>;
9
10#[derive(Clone, Copy, Default)]
11pub struct List<T: Type>(PhantomData<T>);
12
13impl<T: Type> Type for List<T> {}
14
15#[derive(Clone, Copy, Default)]
16pub struct Empty<T: Type>(PhantomData<T>);
17
18#[derive(Clone, Copy, Default)]
19pub struct Segment<I: Value, Next: Value<Type=List<<I as Value>::Type>>>(PhantomData<(I, Next)>);
20
21impl<T: Type> Value for Empty<T> {
22    type Type = List<T>;
23}
24
25impl<T: Type, I: Value<Type=T>, Next: Value<Type=List<T>>> Value for Segment<I, Next> {
26    type Type = List<T>;
27}
28
29pub type Push<I, L> = Eval<PushTo<I>, L>;
30#[derive(Clone, Copy, Default)]
31pub struct PushTo<I: Value>(PhantomData<I>);
32
33impl<T: Type, I: Value<Type=T>> Value for PushTo<I> {
34    type Type = Lambda<List<T>, List<T>>;
35}
36
37impl<T: Type, I: Value<Type=T>, L: Value<Type=List<T>>>  App<L> for PushTo<I> {
38    type Result = Segment<I, L>;
39}
40
41// count
42pub type Contains<I, L> = Eval<ContainIn<I>, L>;
43pub struct ContainIn<I: Value>(PhantomData<I>);
44
45impl<T: Type, I: Value<Type=T>> Value for ContainIn<I> {
46    type Type = Lambda<List<T>, Bool>;
47}
48
49impl<T: Type, I: Value<Type=T>> App<Empty<T>> for ContainIn<I> {
50    type Result = False;
51}
52
53impl<
54    T: Type,
55    I: Value<Type=T>,
56    LI: Value<Type=T>,
57    L: Value<Type=List<T>>,
58    Eq: Value<Type=Bool>,
59    C: Value<Type=Bool>,
60    R: Value<Type=Bool>
61> App<Segment<LI, L>> for ContainIn<I>
62    where
63        EqTo<I>: App<LI, Result=Eq>,
64        ContainIn<I>: App<L, Result=C>,
65        OrOn<Eq>: App<C, Result=R>
66{
67    type Result = R;
68}
69
70pub struct  FilterOn<F: Value>(PhantomData<F>);
71
72impl<T: Type, F: Value<Type=Lambda<T, Bool>>> Value for FilterOn<F> {
73    type Type = Lambda<List<T>, List<T>>;
74}
75
76impl<T: Type, F: Value<Type=Lambda<T, Bool>>> App<Empty<T>>for FilterOn<F> {
77    type Result = Empty<T>;
78}
79
80impl<
81    T: Type,
82    F: Value<Type=Lambda<T, Bool>> + App<Current, Result=CurrentResult>,
83    Current: Value<Type=T>,
84    Next: Value<Type=List<T>>,
85    NextResult: Value<Type=List<T>>,
86    CurrentResult: Value<Type=Bool>,
87    CurrentMaybe: Value<Type=Maybe<T>>,
88    Listed: Value<Type=List<T>>,
89    Result: Value<Type=List<T>>,
90> App<Segment<Current, Next>>for FilterOn<F>
91    where
92        FilterOn<F>: App<Next, Result=NextResult>,
93        WhenMaybe<Just<Current>>: App<CurrentResult, Result=CurrentMaybe>,
94        ToList<T>: App<CurrentMaybe, Result=Listed>,
95        ConcatWith<Next>: App<Listed, Result=Result>
96{
97    type Result = Result;
98}
99
100// concat
101pub type Concat<L1, L2> = Eval<ConcatWith<L1>, L2>;
102pub struct ConcatWith<L: Value>(PhantomData<L>);
103
104impl<T: Type, L: Value<Type=List<T>>> Value for ConcatWith<L> {
105    type Type = Lambda<List<T>, List<T>>;
106}
107
108impl<T: Type, L: Value<Type=List<T>>> App<Empty<T>> for ConcatWith<L> {
109    type Result = L;
110}
111
112impl<
113    T: Type,
114    L: Value<Type=List<T>>,
115    I: Value<Type=T>,
116> App<Segment<I, Empty<T>>> for ConcatWith<L> {
117    type Result = Segment<I, L>;
118}
119
120impl<
121    T: Type,
122    L: Value<Type=List<T>>,
123    I: Value<Type=T>,
124    NextI: Value<Type=T>,
125    Next: Value<Type=List<T>>,
126    NextResult: Value<Type=List<T>>,
127> App<Segment<I, Segment<NextI, Next>>> for ConcatWith<L>
128    where
129        ConcatWith<L>: App<Segment<NextI, Next>, Result=NextResult>
130{
131    type Result = Segment<I, NextResult>;
132}
133
134// Functor
135impl<T: Type> Functor<T> for List<T> {
136    type HKT<A: Type> = List<A>;
137}
138
139impl<
140    A: Type,
141    B: Type,
142    F: Value<Type=Lambda<A, B>>
143> App<Empty<A>> for MapOn<List<A>, F> {
144    type Result = Empty<B>;
145}
146
147impl<
148    A: Type, B: Type,
149    F: Value<Type=Lambda<A, B>> + App<Ia, Result=Ib>,
150    Ia: Value<Type=A>,
151    Ib: Value<Type=B>,
152    La: Value<Type=List<A>>,
153    Lb: Value<Type=List<B>>,
154> App<Segment<Ia, La>> for MapOn<List<A>, F>
155    where
156        MapOn<List<A>, F>: Value<Type=Lambda<List<A>, List<B>>> + App<La, Result=Lb>
157{
158    type Result = Segment<
159        Ib,
160        Lb
161    >;
162}
163
164// Monad
165
166impl<T: Type> Monad for List<T> {
167    type Wrapped = T;
168    type HKT<A: Type> = List<A>;
169}
170
171impl<T: Type, V: Value<Type=T>> App<V> for Pure<List<T>> {
172    type Result = Segment<V, Empty<T>>;
173}
174
175
176impl<
177    A: Type, B: Type,
178    F: Value<Type=Lambda<A, List<B>>>
179> App<Empty<A>> for BindOn<List<A>, F>{
180    type Result = Empty<B>;
181}
182
183impl<
184    A: Type, B: Type,
185    F: Value<Type=Lambda<A, List<B>>> + App<Current, Result=CurrentResult>,
186    Current: Value<Type=A>,
187    Next: Value<Type=List<A>>,
188    CurrentResult: Value<Type=List<B>>,
189    NextResult: Value<Type=List<B>>,
190    Result: Value<Type=List<B>>,
191> App<Segment<Current, Next>> for BindOn<List<A>, F>
192    where
193        BindOn<List<A>, F>: Value + App<Next, Result=NextResult>,
194        ConcatWith<NextResult>: Value + App<CurrentResult, Result=Result>
195{
196    type Result = Result;
197}
198