-
Notifications
You must be signed in to change notification settings - Fork 0
/
monadic_try.rs
72 lines (58 loc) · 1.48 KB
/
monadic_try.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#![feature(try_trait_v2)]
use std::{convert, ops};
#[derive(Debug)]
struct Id<T>(T);
impl<T> ops::FromResidual<<Self as ops::Try>::Residual> for Id<T> {
fn from_residual(residual: <Self as ops::Try>::Residual) -> Self {
match residual {}
}
}
impl<T> ops::Try for Id<T> {
type Output = T;
type Residual = convert::Infallible;
#[inline]
fn from_output(output: Self::Output) -> Self {
Id(output)
}
#[inline]
fn branch(self) -> ops::ControlFlow<Self::Residual, Self::Output> {
ops::ControlFlow::Continue(self.0)
}
}
fn id_sample() -> Id<u8> {
Id(Id(1)? + Id(2)? + Id(3)?)
}
#[derive(Debug)]
struct New<T>(T);
impl<T> ops::FromResidual for New<T>
where
T: ops::FromResidual + ops::Try,
{
#[inline]
#[track_caller]
fn from_residual(residual: <T as ops::Try>::Residual) -> Self {
Self(<T as ops::FromResidual>::from_residual(residual))
}
}
impl<T> ops::Try for New<T>
where
T: ops::Try,
{
type Output = <T as ops::Try>::Output;
type Residual = <T as ops::Try>::Residual;
#[inline]
fn from_output(output: Self::Output) -> Self {
Self(<T as ops::Try>::from_output(output))
}
#[inline]
fn branch(self) -> ops::ControlFlow<Self::Residual, Self::Output> {
self.0.branch()
}
}
fn new_sample() -> New<Result<u8, String>> {
New(Ok(New(Ok(1))? + New(Ok(2))? + New(Ok(3))?))
}
fn main() {
println!("id: {:?}", id_sample());
println!("new: {:?}", new_sample());
}