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
41pub 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
100pub 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
134impl<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
164impl<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