1use std::collections::{LinkedList, VecDeque};
2
3use crate::{Ap, Functor};
4use higher::{Lift, Lift3};
5
6pub 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}