higher_cat/
apply.rs

1use std::collections::{LinkedList, VecDeque};
2
3use crate::{Ap, Functor};
4use higher::{Lift, Lift3};
5
6/// `Apply` takes an `F<Fn(A) -> B>` and applies it to an `F<A>` to produce an
7/// `F<B>`.
8pub trait Apply<A, F, B>: Functor<A, B> + Lift3<A, F, B>
9where
10    F: Fn(A) -> B,
11{
12    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1;
13}
14
15impl<A, F, B> Apply<A, F, B> for Option<A>
16where
17    F: Fn(A) -> B,
18{
19    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1 {
20        self.and_then(|v| f.map(|f| f(v)))
21    }
22}
23
24impl<A, F, B, E> Apply<A, F, B> for Result<A, E>
25where
26    F: Fn(A) -> B,
27{
28    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1 {
29        self.and_then(|v| f.map(|f| f(v)))
30    }
31}
32
33impl<A, F, B> Apply<A, F, B> for Vec<A>
34where
35    A: Clone,
36    F: Fn(A) -> B + Clone,
37{
38    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1 {
39        self.ap(f)
40    }
41}
42
43impl<A, F, B> Apply<A, F, B> for VecDeque<A>
44where
45    A: Clone,
46    F: Fn(A) -> B + Clone,
47{
48    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1 {
49        self.ap(f)
50    }
51}
52
53impl<A, F, B> Apply<A, F, B> for LinkedList<A>
54where
55    A: Clone,
56    F: Fn(A) -> B + Clone,
57{
58    fn apply(self, f: <Self as Lift3<A, F, B>>::Target2) -> <Self as Lift<A, B>>::Target1 {
59        self.ap(f)
60    }
61}