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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Pure.
use crate::higher::Higher;
/// Typeclass for lifting values into a context.
pub trait Pure: Higher {
/// Lift a value into a context.
///
/// # Examples
///
/// ```
/// use rust2fun::prelude::*;
///
/// let actual = Option::pure(1);
/// assert_eq!(Some(1), actual);
/// ```
fn pure(x: Self::Param) -> Self;
/// Lift Unit into a context.
/// This is a convenience method for `pure(())`.
///
/// # Examples
///
/// ```
/// use rust2fun::prelude::*;
///
/// let actual = Option::unit();
/// assert_eq!(Some(()), actual);
/// ```
#[inline]
fn unit() -> Self
where
Self: Higher<Param = ()> + Sized,
{
Self::pure(())
}
}
impl<A> Pure for Option<A> {
#[inline]
fn pure(x: A) -> Option<A> {
Some(x)
}
}
impl<A, E> Pure for Result<A, E> {
#[inline]
fn pure(x: A) -> Self {
Ok(x)
}
}
if_std! {
use std::boxed::Box;
use std::collections::*;
use std::hash::Hash;
use std::vec;
use std::vec::Vec;
impl<A> Pure for Box<A> {
#[inline]
fn pure(x: A) -> Self {
Box::new(x)
}
}
impl<A> Pure for Vec<A> {
#[inline]
fn pure(x: A) -> Self {
vec![x]
}
}
impl<A> Pure for LinkedList<A> {
#[inline]
fn pure(x: A) -> Self {
let mut result = LinkedList::new();
result.push_back(x);
result
}
}
impl<A> Pure for VecDeque<A> {
#[inline]
fn pure(x: A) -> Self {
let mut result = VecDeque::new();
result.push_back(x);
result
}
}
impl<A: Ord> Pure for BinaryHeap<A> {
#[inline]
fn pure(x: A) -> Self {
let mut result = BinaryHeap::new();
result.push(x);
result
}
}
impl<A: Ord> Pure for BTreeSet<A> {
#[inline]
fn pure(x: A) -> Self {
let mut result = BTreeSet::new();
result.insert(x);
result
}
}
impl<A: Eq + Hash> Pure for HashSet<A> {
#[inline]
fn pure(x: A) -> Self {
let mut result = HashSet::new();
result.insert(x);
result
}
}
}