aboutsummaryrefslogtreecommitdiff
path: root/tests/multiple_generics.rs
blob: 2f560ddc815f28c509dd494e4f341f9b797c8612 (plain) (blame)
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
//! Tests if multiple generic parameters work, for the case that lifetimes are independent of mapping functions.
//! For simplicity, it just creates a FreeResult

use higher_free_macro::free;
use higher::{Functor, Bind, Apply};

free!(FreeResult<O,E>, Result<FreeResult<O,E>,E>);

#[test]
fn test_multiple_generics(){
    let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32));
    let m = m.fmap(|x| x*2);
    let m = m.bind(|x| FreeResult::Free(Box::new(Ok(FreeResult::Pure(x)))));
    let f = FreeResult::Pure((|x| x*3).into());
    let m = m.apply(f);
    match m {
        FreeResult::Free(b) => {
            match *b {
                Ok(f) => {
                    match f {
                        FreeResult::Free(b) => {
                            match *b {
                                Ok(f) => {
                                    match f{
                                        FreeResult::Pure(x) => assert_eq!(x, 37*6),
                                        _ => unreachable!()
                                    }
                                }
                                _ => unreachable!()
                            }
                        },
                        _ => unreachable!()
                    }
                }
                _ => unreachable!()
            }
        }
        _ => unreachable!()
    }
}

#[test]
fn test_multiple_generics2(){
    let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32));
    let m = m.bind(|_| FreeResult::<u32, _>::lift_f(Err("An early out.".to_owned())));
    match m{
        FreeResult::Free(m) => {
            match &*m {
                Ok(m) => {
                    match m{
                        FreeResult::Free(m) => {
                            match &**m {
                                Err(e) => assert_eq!(e, "An early out."),
                                _ => unreachable!()
                            }
                        }
                        _ => unreachable!()
                    }
                },
                _ => unreachable!()
            }
        },
        _ => unreachable!()
    }
}

#[test]
fn test_multiple_generics3(){
    let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32));
    let f : FreeResult<_, String> = FreeResult::Pure(|x : u32| -> f32 {(x as f32)*0.5f32}).fmap(Into::into);
    let m = m.apply(f);
    match m{
        FreeResult::Free(m) => {
            match &*m{
                Ok(k) => {
                    match k {
                        FreeResult::Pure(k) => assert_eq!(18.5f32, *k),
                        FreeResult::Free(_) => unreachable!(),
                    }
                }
                Err(_) => unreachable!(),
            }
        },
        _ => unreachable!()
    }
}