Some Implementation in Swift.
Functor
Let $C$ be a constructor which takes a variable as parameter.
$C$ is a Functor if $C$ has the following ability.
For example, we can write such a function functor
or map
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 class Box<T> {
var content: T
init(content: T) {
self.content = content
}
func functor<U>(_ relation: (T) > U) > Box<U> {
return Box<U>(content: relation(self.content))
}
}
func functor<T, U>(box: Box<T>, relation: (T) > U) > Box<U> {
return Box(content: relation(box.content))
}
let a = Box(content: 1)
let b = functor(box: a, relation: { $0 + 100 }).content
b // 101

And we can chain functors like this.
1
2
3
 let addup: (Int)>Int = { $0 + 1 }
let c = a.functor(addup).functor(addup).content
c // 3

We can also do it like Haskell
1
2
3
4
5
6
7
8
9
10
 precedencegroup chainopts {
associativity: left
}
infix operator <^>: chainopts
func <^><T, U>(a: Box<T>, f: (T) > U) > Box<U> {
return a.functor(f)
}
let d = a <^> addup <^> addup
d.content // 3

Monad
$C$ is a Monad if $C$ has the following ability. This is also called as flatmap
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 class Box<T> {
var content: T
init(content: T) {
self.content = content
}
func monad<U>(_ relation: (T) > Box<U>) > Box<U> {
return relation(self.content)
}
}
func monad<T, U>(box: Box<T>, relation: (T) > Box<U>) > Box<U> {
return relation(box.content)
}
let e = monad(box: a, relation: { Box(content: $0 + 1000) } ).content
e // 1001
let addupAndWrap: (Int)>Box<Int> = { Box(content: $0 + 1000) }
let f = a.monad(addupAndWrap).monad(addupAndWrap).content
f // 2001

Haskelllike version.
1
2
3
4
5
6
 infix operator >>: chainopts
func >><T, U>(a: Box<T>, f: (T) > Box<U>) > Box<U> {
return a.monad(f)
}
let g = a >> addupAndWrap >> addupAndWrap
g.content // 2001

Applicative
$C$ is a Applicative if $C$ has the following ability.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 class Box<T> {
var content: T
init(content: T) {
self.content = content
}
func apply<U>(_ relation: Box<(T) > U>) > Box<U> {
return Box<U>(content: relation.content(self.content))
}
}
func apply<T, U>(box: Box<T>, relation: Box<(T) > U>) > Box<U> {
return Box(content: relation.content(box.content))
}
let h = apply(box: a, relation: Box(content: {$0 + 10000} )).content
h // 10001
let anBoxContainsAddup: Box<(Int)>Int> = Box(content: {$0 + 10000} )
let i = a.apply(anBoxContainsAddup).apply(anBoxContainsAddup).content
i // 20001

Haskelllike version.
1
2
3
4
5
6
 infix operator <*>: chainopts
func <*><T, U>(a: Box<T>, f: Box<(T) > U>) > Box<U> {
return a.apply(f)
}
let j = a <*> anBoxContainsAddup <*> anBoxContainsAddup
j.content // 20001
