Repository navigation
Expand file tree
/
Copy pathOperators.swift
More file actions
95 lines (84 loc) · 2.75 KB
/
Copy pathOperators.swift
File metadata and controls
95 lines (84 loc) · 2.75 KB
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
87
88
89
90
91
92
93
94
95
import Foundation
// The default precedence is 100.
operator infix <%> { associativity left }
operator infix >>= { associativity left precedence 80 }
operator infix <*> { associativity left }
operator infix <* { associativity left }
operator infix *> { associativity left }
operator infix <|> { associativity left precedence 90 }
operator infix <% { associativity left }
operator infix <**> { associativity left }
// Functor
func <%><u, a, t>(f: t -> a, parser: Parser<u, t>) -> Parser<u, a> {
let f: Stream<u> -> Reply<a> = { (var stream) in
switch (parser.Run(stream)) {
case .Lovely(let result):
return Reply.Lovely(f(result))
case .Error(let error):
return Reply.Error(error)
}
}
return Thunk(thunk: f)
}
// Applicative
func pure<u, a>(x: a) -> Parser<u, a> {
let f: Stream<u> -> Reply<a> = { (var stream) in
return Reply.Lovely(x)
}
return Thunk(thunk: f)
}
func <*><u, a, t>(parserF: Parser<u, t -> a>, parser: Parser<u, t>) -> Parser<u, a> {
let f: Stream<u> -> Reply<a> = { (var stream) in
switch (parserF.Run(stream)) {
case .Lovely(let g):
switch (parser.Run(stream)) {
case .Lovely(let result):
return Reply.Lovely(g(result))
case .Error(let error):
return Reply.Error(error)
}
case .Error(let error):
return Reply.Error(error)
}
}
return Thunk(thunk: f)
}
func <**><u, a, t>(parser: Parser<u, t>, parserF: Parser<u, t -> a>) -> Parser<u, a> {
return parserF <*> parser;
}
func <*<u, a, b>(left: Parser<u, a>, right: Parser<u, b>) -> Parser<u, a> {
return { a in { b in a } } <%> left <*> right;
}
func *><u, a, b>(left: Parser<u, a>, right: Parser<u, b>) -> Parser<u, b> {
return { a in { b in b } } <%> left <*> right;
}
// Alternative
func <|><u, a>(left: Parser<u, a>, right: Parser<u, a>) -> Parser<u, a> {
let f: Stream<u> -> Reply<a> = { (var stream) in
let snapshot = stream.Snapshot()
switch (left.Run(stream)) {
case .Lovely(let result):
return Reply.Lovely(result)
case .Error(let error):
stream.Rewind(snapshot)
return right.Run(stream)
}
}
return Thunk(thunk: f)
}
// Monad
func >>=<u, a, t>(parser: Parser<u, t>, binder: t -> Parser<u, a>) -> Parser<u, a> {
let f: Stream<u> -> Reply<a> = { (var stream) in
switch (parser.Run(stream)) {
case .Lovely(let result):
return binder(result).Run(stream)
case .Error(let error):
return Reply.Error(error)
}
}
return Thunk(thunk: f)
}
// Utility functions
func <%<u, a, t>(x: a, left: Parser<u, t>) -> Parser<u, a> {
return { _ in x } <%> left
}