more exercises
This commit is contained in:
parent
4172ee7427
commit
e9cf323ca2
@ -3,4 +3,7 @@
|
||||
[Overview](./overview.md)
|
||||
|
||||
- [Chapter 1](./chapter_1.md)
|
||||
- [`A`/`A1`/`A2`](./exercises/multiple_blanket.md)
|
||||
- [test0.rs (bind)](./exercises/bind.md)
|
||||
- [test1.rs (refbind)](./exercises/refbind.md)
|
||||
- [A/A1/A2](./exercises/multiple_blanket.md)
|
||||
- [BoolStream](./exercises/bool_stream.md)
|
||||
|
27
src/exercises/bind.md
Normal file
27
src/exercises/bind.md
Normal file
@ -0,0 +1,27 @@
|
||||
```rust
|
||||
# mod __ {
|
||||
fn bind<T, F: FnOnce(T) -> Option<T>>(f: F, fa: Option<T>) -> Option<T> {
|
||||
match fa {
|
||||
Some(a) => f(a),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
# }
|
||||
# fn bind<T, F: FnOnce(T) -> Option<T>>(f: F, fa: Option<T>) -> Option<T> { fa.and_then(f) }
|
||||
|
||||
// don't change anything below
|
||||
|
||||
assert_eq!(bind(|x: i32| Some(x + 3), Some(2)), Some(5));
|
||||
assert_eq!(bind(|x: i32| Some(x + 3), None), None);
|
||||
assert_eq!(bind(|_: i32| None, Some(2)), None);
|
||||
assert_eq!(bind(|_: i32| None, None), None);
|
||||
|
||||
assert_eq!(bind(|x: &str| Some(x), Some("apple")), Some("apple"));
|
||||
assert_eq!(bind(|_: &str| Some("banana"), Some("apple")), Some("banana"));
|
||||
|
||||
let banana = "banana".to_string();
|
||||
assert_eq!(
|
||||
bind(|_: String| Some(banana), Some("apple".to_string())),
|
||||
Some("banana".to_string()),
|
||||
);
|
||||
```
|
61
src/exercises/bool_stream.md
Normal file
61
src/exercises/bool_stream.md
Normal file
@ -0,0 +1,61 @@
|
||||
Make `test_covariance` compile by making `BoolStream<'a>` covariant `'a`.
|
||||
- Can only change implementation details of `BoolStream` and its methods and add extra items outside of what's given, i.e. no signature/test change.
|
||||
- Changed version must behave the same way.
|
||||
```rust
|
||||
pub struct BoolStream<'a>(
|
||||
// change this
|
||||
# /*
|
||||
Box<dyn 'a + FnOnce() -> (bool, BoolStream<'a>)>,
|
||||
# */ Box<dyn 'a + Next>
|
||||
);
|
||||
|
||||
impl<'a> BoolStream<'a> {
|
||||
pub fn new(f: impl 'a + FnOnce() -> (bool, Self)) -> Self {
|
||||
// maybe change this
|
||||
# /*
|
||||
Self(Box::new(f))
|
||||
# */ Self(Box::new(Wrapper(f, PhantomData)))
|
||||
}
|
||||
|
||||
pub fn next(self) -> (bool, Self) {
|
||||
// maybe change this
|
||||
# /*
|
||||
self.0()
|
||||
# */ self.0.next()
|
||||
}
|
||||
}
|
||||
|
||||
fn test_covariance<'a: 'b, 'b>(e: BoolStream<'a>) -> BoolStream<'b> {
|
||||
e
|
||||
}
|
||||
|
||||
# use std::marker::PhantomData;
|
||||
# struct Wrapper<'a, F>(F, PhantomData<&'a ()>);
|
||||
# trait Next {
|
||||
# fn next<'t>(self: Box<Self>) -> (bool, BoolStream<'t>) where Self: 't;
|
||||
# }
|
||||
# impl<'a, F: 'a + FnOnce() -> (bool, BoolStream<'a>)> Next for Wrapper<'a, F> {
|
||||
# fn next<'t>(self: Box<Self>) -> (bool, BoolStream<'t>) where Self: 't { self.0() }
|
||||
# }
|
||||
|
||||
/// Tests to check that behaviour stays the same.
|
||||
|
||||
fn get_true<'a>() -> BoolStream<'a> {
|
||||
BoolStream::new(|| (true, get_false()))
|
||||
}
|
||||
|
||||
fn get_false<'a>() -> BoolStream<'a> {
|
||||
BoolStream::new(|| (false, get_true()))
|
||||
}
|
||||
|
||||
let e = get_true();
|
||||
let (x, e) = e.next();
|
||||
assert!(x);
|
||||
let (x, e) = e.next();
|
||||
assert!(!x);
|
||||
let (x, e) = e.next();
|
||||
assert!(x);
|
||||
let (x, e) = e.next();
|
||||
assert!(!x);
|
||||
test_covariance(e);
|
||||
```
|
@ -1,9 +1,13 @@
|
||||
Make this compile.
|
||||
- `A1` doesn't know about/depend on `A2`
|
||||
- `A2` doesn't know about/depend on `A1`
|
||||
- `A1` doesn't know about/depend on `A`
|
||||
- `A2` doesn't know about/depend on `A`
|
||||
- can't edit definitions of `A`, `test`, `tes1`, `test2`; can only add code outside of those items
|
||||
- `A1` doesn't know about/depend on `A2`.
|
||||
- `A2` doesn't know about/depend on `A1`.
|
||||
- `A1` doesn't know about/depend on `A`.
|
||||
- `A2` doesn't know about/depend on `A`.
|
||||
- Some types are `A1` but not `A2`.
|
||||
- Some types are `A2` but not `A1`.
|
||||
- Some types are `A` but not `A2`.
|
||||
- Some types are `A` but not `A1`.
|
||||
- Can't edit definitions of `A`, `test`, `tes1`, `test2`; can only add code outside of those items.
|
||||
```rust
|
||||
trait A {
|
||||
fn a_ref(&self) -> u64;
|
||||
|
26
src/exercises/refbind.md
Normal file
26
src/exercises/refbind.md
Normal file
@ -0,0 +1,26 @@
|
||||
```rust
|
||||
# mod __ {
|
||||
fn refbind<T, F: Fn(&T) -> Option<&T>>(f: F, fa: Option<&T>) -> Option<&T> {
|
||||
match fa {
|
||||
Some(a) => f(a),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
# }
|
||||
# fn refbind<'a,'b,T:'a+?Sized>(f:impl'a+Fn(&'a T)->Option<&'b T>,fa:Option<&'a T>)->Option<&'b T>{fa.and_then(f)}
|
||||
|
||||
// don't change anything below
|
||||
|
||||
let apple = "apple".to_string();
|
||||
let banana = "banana".to_string();
|
||||
assert_eq!(
|
||||
refbind(|_: &String| Some(&banana), Some(&apple)),
|
||||
Some(&banana)
|
||||
);
|
||||
|
||||
let banana = "banana";
|
||||
assert_eq!(
|
||||
refbind(|_: &str| Some(banana), Some("apple")),
|
||||
Some(banana)
|
||||
);
|
||||
```
|
@ -21,10 +21,10 @@ Some exercises may not include have the replaced parts greyed out:
|
||||
```rust
|
||||
# mod __ {
|
||||
fn fix_me() {
|
||||
# }
|
||||
}
|
||||
# }
|
||||
# fn fixed_name() {
|
||||
}
|
||||
# }
|
||||
|
||||
fn do_not_change_this() {
|
||||
fixed_name()
|
||||
|
Loading…
Reference in New Issue
Block a user