more exercises
This commit is contained in:
parent
4172ee7427
commit
e9cf323ca2
@ -3,4 +3,7 @@
|
|||||||
[Overview](./overview.md)
|
[Overview](./overview.md)
|
||||||
|
|
||||||
- [Chapter 1](./chapter_1.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.
|
Make this compile.
|
||||||
- `A1` doesn't know about/depend on `A2`
|
- `A1` doesn't know about/depend on `A2`.
|
||||||
- `A2` doesn't know about/depend on `A1`
|
- `A2` doesn't know about/depend on `A1`.
|
||||||
- `A1` doesn't know about/depend on `A`
|
- `A1` doesn't know about/depend on `A`.
|
||||||
- `A2` 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
|
- 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
|
```rust
|
||||||
trait A {
|
trait A {
|
||||||
fn a_ref(&self) -> u64;
|
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
|
```rust
|
||||||
# mod __ {
|
# mod __ {
|
||||||
fn fix_me() {
|
fn fix_me() {
|
||||||
# }
|
}
|
||||||
# }
|
# }
|
||||||
# fn fixed_name() {
|
# fn fixed_name() {
|
||||||
}
|
# }
|
||||||
|
|
||||||
fn do_not_change_this() {
|
fn do_not_change_this() {
|
||||||
fixed_name()
|
fixed_name()
|
||||||
|
Loading…
Reference in New Issue
Block a user