ch04 reorg
This commit is contained in:
		
							parent
							
								
									509ffacd4c
								
							
						
					
					
						commit
						21e4496201
					
				
							
								
								
									
										13
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,14 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "rust-analyzer.showUnlinkedFileNotification": false
 | 
					    "rust-analyzer.showUnlinkedFileNotification": false,
 | 
				
			||||||
 | 
					    "[rust]": {
 | 
				
			||||||
 | 
					        "editor.rulers": [
 | 
				
			||||||
 | 
					            100
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "[markdown]": {
 | 
				
			||||||
 | 
					        "editor.rulers": [
 | 
				
			||||||
 | 
					            99,
 | 
				
			||||||
 | 
					            100
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -6,6 +6,7 @@ src = "src"
 | 
				
			|||||||
title = "Monads in Rust"
 | 
					title = "Monads in Rust"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[build]
 | 
					[build]
 | 
				
			||||||
 | 
					build-dir = "book"
 | 
				
			||||||
create-missing = false
 | 
					create-missing = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[output.html]
 | 
					[output.html]
 | 
				
			||||||
 | 
				
			|||||||
@ -6,3 +6,7 @@
 | 
				
			|||||||
- [Implementation](./ch02/s00-implementation.md)
 | 
					- [Implementation](./ch02/s00-implementation.md)
 | 
				
			||||||
- [Usage]()
 | 
					- [Usage]()
 | 
				
			||||||
- [Current Implementation Concerns](./ch04/s00-concerns.md)
 | 
					- [Current Implementation Concerns](./ch04/s00-concerns.md)
 | 
				
			||||||
 | 
					  - [Alternative Monad Traits](./ch04/s01-alternatives.md)
 | 
				
			||||||
 | 
					  - [Lifetimes](./ch04/s02-lifetimes.md)
 | 
				
			||||||
 | 
					  - [Stackless](./ch04/s03-stackless.md)
 | 
				
			||||||
 | 
					  - [Covariance](./ch04/s04-covariance.md)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,32 +1,19 @@
 | 
				
			|||||||
# Concerns (questions) with the current implementaion
 | 
					# Concerns (questions) with the current implementaion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## There exist alternative `Functor` implementations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the [relevant subchapter](s01-alternatives.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## It might be better to have a per-lifetime trait for `Functor`s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the [relevant subchapter](s02-lifetimes.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `Stackless` is kind of bad
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the [relevant subchapter](s03-stackless.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `WeakFunctor::F<'a, A>` is not (yet) covariant over the lifetime `'a`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the [relevant subchapter](s04-covariance.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Can `WeakFunctor` be an associated type of a `Functor` instead of its supertype?
 | 
					## Can `WeakFunctor` be an associated type of a `Functor` instead of its supertype?
 | 
				
			||||||
 | 
					 | 
				
			||||||
## `Clone`-`FnMut` category functors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## `Copy`-`Fn` category functors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## `WeakFunctor::F<'a, A>` is not (yet) covariant over the lifetime `'a`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Specific case: `Stackless<'a>` isn't covariant.
 | 
					 | 
				
			||||||
Current hypothesis is that this comes from `EvalTree<'a>` being invariant over `'a`
 | 
					 | 
				
			||||||
due to `FnOnce` being invariant over its output,
 | 
					 | 
				
			||||||
which in turn comes from present typesysten limitations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## It might be better to have a per-lifetime trait for `Functor`s.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Current:
 | 
					 | 
				
			||||||
```rust
 | 
					 | 
				
			||||||
pub trait WeakFunctor {
 | 
					 | 
				
			||||||
    type F<'a, A: 'a>: 'a
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: 'a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Proposed:
 | 
					 | 
				
			||||||
```rust
 | 
					 | 
				
			||||||
pub trait WeakFunctor<'a>: 'a {
 | 
					 | 
				
			||||||
    type F<A: 'a>: 'a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										97
									
								
								book/src/ch04/s01-alternatives.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								book/src/ch04/s01-alternatives.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					# Atlernatives to `Functor` trait
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `_`-`FnOnce` category functors (current)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copied for reference. All following examples are in the same `Functor`-`Applicative`-`Monad` format
 | 
				
			||||||
 | 
					without extra (sub)traits like `WeakFunctor`, `Pure`, `ApplicativeLA2`, etc. .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					trait Functor {
 | 
				
			||||||
 | 
					    type F<'a, A: 'a>: 'a
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn fmap<'a, A: 'a, B: 'a>(
 | 
				
			||||||
 | 
					        f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>,
 | 
				
			||||||
 | 
					    ) -> Self::F<'a, B>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fmap<'a, T: 'a + Functor, A: 'a, B: 'a>(
 | 
				
			||||||
 | 
					    f: impl 'a + FnOnce(A) -> B,
 | 
				
			||||||
 | 
					) -> impl FnOnce(T::F<'a, A>) -> T::F<'a, B> {
 | 
				
			||||||
 | 
					    |fa| T::fmap(f, fa)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `Clone`-`Fn` category functors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is probably the closest representation to what Haskell views as a category of its types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					trait Functor: Clone {
 | 
				
			||||||
 | 
					    type F<'a, A: 'a + Clone>: 'a + Clone
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn fmap<'a, A: 'a + Clone, B: 'a + Clone>(
 | 
				
			||||||
 | 
					        f: impl 'a + Clone + Fn(A) -> B, fa: Self::F<'a, A>,
 | 
				
			||||||
 | 
					    ) -> Self::F<'a, B>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fmap<'a, T: 'a + Functor, A: 'a + Clone, B: 'a + Clone>(
 | 
				
			||||||
 | 
					    f: impl 'a + Clone + Fn(A) -> B,
 | 
				
			||||||
 | 
					) -> impl 'a + Clone + Fn(T::F<'a, A>) -> T::F<'a, B> {
 | 
				
			||||||
 | 
					    move |fa| T::fmap(f.clone(), fa)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `Clone`-`FnMut` category functors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We view use of `FnMut` for category's morphisms as somewhat controversial[^e].
 | 
				
			||||||
 | 
					* Use of direct/indirect mutable references is, arguably, counter-functional[^e].
 | 
				
			||||||
 | 
					* `Clone+FnMut` is, generally, nonsensical[^e].
 | 
				
			||||||
 | 
					* Due to that, morphisms category isn't a subcategory, so can't be wrapped.
 | 
				
			||||||
 | 
					* Not being to wrap morphisms makes implementation of one specific `Applicative` method,
 | 
				
			||||||
 | 
					sequential application (`<*>` in Haskell, `seq` in RADN) *difficult*.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					trait Functor: Clone {
 | 
				
			||||||
 | 
					    type F<'a, A: 'a + Clone>: 'a + Clone
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn fmap<'a, A: 'a + Clone, B: 'a + Clone>(
 | 
				
			||||||
 | 
					        f: impl 'a + FnMut(A) -> B, fa: Self::F<'a, A>,
 | 
				
			||||||
 | 
					    ) -> Self::F<'a, B>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[^e]: elaborate?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## `Copy`-`Fn` category functors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					trait Functor: Copy {
 | 
				
			||||||
 | 
					    type F<'a, A: 'a + Copy>: 'a + Copy
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn fmap<'a, A: 'a + Copy, B: 'a + Copy>(
 | 
				
			||||||
 | 
					        f: impl 'a + Copy + Fn(A) -> B, fa: Self::F<'a, A>,
 | 
				
			||||||
 | 
					    ) -> Self::F<'a, B>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fmap<'a, T: 'a + Functor, A: 'a + Copy, B: 'a + Copy>(
 | 
				
			||||||
 | 
					    f: impl 'a + Copy + Fn(A) -> B,
 | 
				
			||||||
 | 
					) -> impl 'a + Copy + Fn(T::F<'a, A>) -> T::F<'a, B> {
 | 
				
			||||||
 | 
					    move |fa| T::fmap(f, fa)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										18
									
								
								book/src/ch04/s02-lifetimes.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								book/src/ch04/s02-lifetimes.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Making lifetimes a parameter of a trait instead of that of the GAT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Current:
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					pub trait WeakFunctor {
 | 
				
			||||||
 | 
					    type F<'a, A: 'a>: 'a
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        Self: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Proposed:
 | 
				
			||||||
 | 
					```rust
 | 
				
			||||||
 | 
					pub trait WeakFunctor<'a>: 'a {
 | 
				
			||||||
 | 
					    type F<A: 'a>: 'a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								book/src/ch04/s03-stackless.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								book/src/ch04/s03-stackless.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					# `Stackless<'a>` isn't covariant
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Current hypothesis is that this comes from `EvalTree<'a>` being invariant over `'a`
 | 
				
			||||||
 | 
					due to `FnOnce` being invariant over its output,
 | 
				
			||||||
 | 
					which in turn comes from present typesysten limitations.
 | 
				
			||||||
							
								
								
									
										5
									
								
								book/src/ch04/s04-covariance.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								book/src/ch04/s04-covariance.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					## `CovariantFunctor` not (yet) included in `Monad`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Specific case: `Stackless<'a>` isn't covariant
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the [relevant subchapter](s03-stackless.md)
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user