-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathFunctor.re
38 lines (32 loc) · 911 Bytes
/
Functor.re
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
module type Functor = {
type t('a);
let fmap: ('a => 'b, t('a)) => t('b);
};
module FunctorUtils = (F: Functor) => {
open Base;
include F;
let (<$>) = (f, x) => fmap(f, x);
let (<&>) = (x, f) => flip(fmap, x, f);
let (<$) = (r, x) => fmap(const(r), x);
let ($>) = (r, x) => flip((<$), r, x);
let void = (f, x) => fmap(x => ignore(f(x)), x);
};
module FunctorLaws = (F: Functor) => {
open Base;
open F;
let idLaw = x => fmap(id, x) == x;
let composeLaw = (f, g, xs) => fmap(f <<< g, xs) == fmap(f, fmap(g, xs));
};
module ListF_: Functor with type t('a) = list('a) = {
type t('a) = list('a);
let fmap = f => List.map(f);
};
module ListFunctor = FunctorUtils(ListF_);
module OptionF_: Functor with type t('a) = option('a) = {
type t('a) = option('a);
let fmap = f =>
fun
| Some(x) => Some(f(x))
| None => None;
};
module OptionFunctor = FunctorUtils(OptionF_);