composition
This commit is contained in:
parent
e020a098d0
commit
3fc4bd260c
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,14 +1,3 @@
|
|||||||
book
|
book
|
||||||
|
target
|
||||||
|
Cargo.lock
|
||||||
# Added by cargo
|
|
||||||
|
|
||||||
/target
|
|
||||||
|
|
||||||
|
|
||||||
# Added by cargo
|
|
||||||
#
|
|
||||||
# already existing elements were commented out
|
|
||||||
|
|
||||||
#/target
|
|
||||||
/Cargo.lock
|
|
||||||
|
@ -11,5 +11,7 @@
|
|||||||
- [Chapter 2](./chapter_2.md)
|
- [Chapter 2](./chapter_2.md)
|
||||||
- [AnyStr](./exercises/anystr.md)
|
- [AnyStr](./exercises/anystr.md)
|
||||||
- [Mode](./exercises/mode.md)
|
- [Mode](./exercises/mode.md)
|
||||||
|
- [Chapter 3](./chapter_3.md)
|
||||||
|
- [Composition](./exercises/composition.md)
|
||||||
|
|
||||||
[Topics (Spoilers)](./topics.md)
|
[Topics (Spoilers)](./topics.md)
|
||||||
|
1
src/chapter_3.md
Normal file
1
src/chapter_3.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Chapter 3
|
115
src/exercises/composition.md
Normal file
115
src/exercises/composition.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
```rust
|
||||||
|
# use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
trait Monad<'a>: 'a {
|
||||||
|
type W<A: 'a>: 'a;
|
||||||
|
|
||||||
|
fn map<A: 'a, B: 'a>(
|
||||||
|
wa: Self::W<A>,
|
||||||
|
f: impl FnOnce(A) -> B,
|
||||||
|
) -> Self::W<B>;
|
||||||
|
|
||||||
|
fn pure<A: 'a>(
|
||||||
|
a: A,
|
||||||
|
) -> Self::W<A>;
|
||||||
|
|
||||||
|
fn collect<A: 'a, B: 'a>(
|
||||||
|
wab: (Self::W<A>, Self::W<B>),
|
||||||
|
) -> Self::W<(A, B)>;
|
||||||
|
|
||||||
|
fn bind<A: 'a, B: 'a>(
|
||||||
|
wa: Self::W<A>,
|
||||||
|
f: impl FnOnce(A) -> Self::W<B>,
|
||||||
|
) -> Self::W<B>;
|
||||||
|
|
||||||
|
fn iterate<A: 'a>(
|
||||||
|
i: impl Iteration<'a, A = A, M = Self>,
|
||||||
|
) -> Self::W<A>;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Iteration<'a>: 'a + Sized {
|
||||||
|
type A: 'a;
|
||||||
|
|
||||||
|
type M: ?Sized + Monad<'a>;
|
||||||
|
|
||||||
|
fn next(self) -> IWrap<'a, Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Wrap<'a, M, A> = <M as Monad<'a>>::W<A>;
|
||||||
|
|
||||||
|
type IOutput<'a, I> = ControlFlow<<I as Iteration<'a>>::A, I>;
|
||||||
|
|
||||||
|
type IWrap<'a, I> = Wrap<'a, <I as Iteration<'a>>::M, IOutput<'a, I>>;
|
||||||
|
|
||||||
|
struct Composition<U, V>(U, V);
|
||||||
|
|
||||||
|
impl<'a, U, V> Monad<'a> for Composition<U, V>
|
||||||
|
where
|
||||||
|
U: Monad<'a>,
|
||||||
|
V: Monad<'a>,
|
||||||
|
// something missing here?
|
||||||
|
# V: Local<'a>,
|
||||||
|
{
|
||||||
|
type W<A: 'a> = U::W<V::W<A>>;
|
||||||
|
|
||||||
|
fn map<A: 'a, B: 'a>(
|
||||||
|
wa: Self::W<A>,
|
||||||
|
f: impl FnOnce(A) -> B,
|
||||||
|
) -> Self::W<B> {
|
||||||
|
U::map(wa, |va| V::map(va, f))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pure<A: 'a>(
|
||||||
|
a: A,
|
||||||
|
) -> Self::W<A> {
|
||||||
|
U::pure(V::pure(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect<A: 'a, B: 'a>(
|
||||||
|
wab: (Self::W<A>, Self::W<B>),
|
||||||
|
) -> Self::W<(A, B)> {
|
||||||
|
U::map(U::collect(wab), V::collect)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind<A: 'a, B: 'a>(
|
||||||
|
wa: Self::W<A>,
|
||||||
|
f: impl FnOnce(A) -> Self::W<B>,
|
||||||
|
) -> Self::W<B> {
|
||||||
|
// impossible
|
||||||
|
# U::bind(wa, |va| U::map(V::wrap::<_, U>(V::map(va, f)), |vvb| V::bind(vvb, |vb| vb)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iterate<A: 'a>(
|
||||||
|
i: impl Iteration<'a, A = A, M = Self>,
|
||||||
|
) -> Self::W<A> {
|
||||||
|
// impossible
|
||||||
|
# U::iterate(ComposedIteration(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# trait Local<'a>: Monad<'a> { fn wrap<A: 'a, M: Monad<'a>>(wa: Self::W<M::W<A>>) -> M::W<Self::W<A>>; }
|
||||||
|
# struct CfInstance<E>(ControlFlow<(), E>);
|
||||||
|
# use ControlFlow::{Continue, Break};
|
||||||
|
# impl<'a, E: 'a> Monad<'a> for CfInstance<E> {
|
||||||
|
# type W<A: 'a> = ControlFlow<A, E>;
|
||||||
|
# fn map<A: 'a, B: 'a>(wa: Self::W<A>, f: impl FnOnce(A) -> B) -> Self::W<B> {
|
||||||
|
# match wa { Continue(c) => Continue(c), Break(a) => Break(f(a)) }
|
||||||
|
# }
|
||||||
|
# fn pure<A: 'a>(a: A) -> Self::W<A> { Break(a) }
|
||||||
|
# fn collect<A: 'a, B: 'a>(wab: (Self::W<A>, Self::W<B>)) -> Self::W<(A, B)> {
|
||||||
|
# match wab { (Continue(e), _) => Continue(e), (_, Continue(e)) => Continue(e), (Break(a), Break(b)) => Break((a, b)) }
|
||||||
|
# }
|
||||||
|
# fn bind<A: 'a, B: 'a>(wa: Self::W<A>, f: impl FnOnce(A) -> Self::W<B>) -> Self::W<B> {
|
||||||
|
# match wa { Continue(e) => Continue(e), Break(a) => f(a) }
|
||||||
|
# }
|
||||||
|
# fn iterate<A: 'a>(mut i: impl Iteration<'a, A = A, M = Self>) -> Self::W<A> {
|
||||||
|
# loop { match i.next() { Continue(e) => break Continue(e), Break(Continue(next_i)) => i = next_i, Break(Break(a)) => break Break(a) } }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# struct ComposedIteration<F>(F);
|
||||||
|
# impl<'a, U: Monad<'a>, V: Local<'a>, F: Iteration<'a, M = Composition<U, V>>> Iteration<'a> for ComposedIteration<F> {
|
||||||
|
# type A = Wrap<'a, V, F::A>;
|
||||||
|
# type M = U;
|
||||||
|
# fn next(self) -> IWrap<'a, Self> { U::map(self.0.next(), |vstate| { ControlFlow::Continue(Self(V::wrap::<_, CfInstance<_>>(vstate)?)) }) }
|
||||||
|
# }
|
||||||
|
```
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
Rows are ordered based on estimated difficulty.
|
Rows are ordered based on estimated difficulty.
|
||||||
|
|
||||||
| lifetimes | `trait`s | `struct`s |
|
| lifetimes\[-adjacent\] | `trait`s | `struct`s |
|
||||||
|------------------------|--------------------|-------------|
|
|------------------------|--------------------|-------------|
|
||||||
| [explicit lifetimes] | [`Fn`?] | |
|
| [explicit lifetimes] | [`Fn`?] | |
|
||||||
| [extracting lifetimes] | [exclusive traits] | [`RcChars`] |
|
| [extracting lifetimes] | [exclusive traits] | [`RcChars`] |
|
||||||
| | [`AnyStr`] | |
|
| [composition] | [`AnyStr`] | |
|
||||||
| | [merging traits] | |
|
| | [merging traits] | |
|
||||||
|
|
||||||
|
|
||||||
@ -17,3 +17,4 @@ Rows are ordered based on estimated difficulty.
|
|||||||
[exclusive traits]: ./exercises/multiple_blanket.md
|
[exclusive traits]: ./exercises/multiple_blanket.md
|
||||||
[merging traits]: ./exercises/modes.md
|
[merging traits]: ./exercises/modes.md
|
||||||
[`AnyStr`]: ./exercises/anystr.md
|
[`AnyStr`]: ./exercises/anystr.md
|
||||||
|
[composition]: ./exercises/composition.md
|
||||||
|
Loading…
Reference in New Issue
Block a user