Skip to content

Commit f792c45

Browse files
authored
Reorganize Prelude (#2)
* Reorganize Prelude * Feedback + tests
1 parent 98dc978 commit f792c45

25 files changed

+496
-368
lines changed

Prelude.xcodeproj/project.pbxproj

+167-83
Large diffs are not rendered by default.

Sources/Prelude/Array.swift

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
public func uncons<A>(_ xs: [A]) -> (A, [A])? {
2+
guard let x = xs.first else { return nil }
3+
return (x, Array(xs.dropFirst()))
4+
}
5+
6+
public func <¢> <A, B> (f: (A) -> B, xs: [A]) -> [B] {
7+
return xs.map(f)
8+
}
9+
10+
public func <*> <A, B> (fs: [(A) -> B], xs: [A]) -> [B] {
11+
return fs.flatMap { f in xs.map(f) }
12+
}
13+
14+
public func foldMap<A, M: Monoid>(_ f: @escaping (A) -> M) -> ([A]) -> M {
15+
return { xs in
16+
xs.reduce(M.e) { accum, x in accum <> f(x) }
17+
}
18+
}
19+
20+
public func partition<A>(_ p: @escaping (A) -> Bool) -> ([A]) -> ([A], [A]) {
21+
return { xs in
22+
xs.reduce(([], [])) { accum, x in
23+
p(x) ? (accum.0 + [x], accum.1) : (accum.0, accum.1 + [x])
24+
}
25+
}
26+
}
27+
28+
public func elem<A: Equatable>(_ x: A) -> ([A]) -> Bool {
29+
return { xs in xs.contains(x) }
30+
}
31+
32+
public func elem<A: Equatable>(of xs: [A]) -> (A) -> Bool {
33+
return { x in xs.contains(x) }
34+
}
35+
36+
public func zipWith<A, B, C>(_ f: @escaping (A, B) -> C) -> ([A]) -> ([B]) -> [C] {
37+
return { xs in
38+
return { ys in
39+
return zip(xs, ys).map { f($0.0, $0.1) }
40+
}
41+
}
42+
}
43+
44+
public func sorted<A>(by f: @escaping (A, A) -> Bool) -> ([A]) -> [A] {
45+
return { xs in
46+
xs.sorted(by: f)
47+
}
48+
}
49+
50+
public func lookup<A: Equatable, B>(_ x: A) -> ([(A, B)]) -> B? {
51+
return { pairs in
52+
pairs.first { pair in pair.0 == x }.map(second)
53+
}
54+
}
55+
56+
public func catOptionals<A>(_ xs: [A?]) -> [A] {
57+
return xs |> mapOptional(id)
58+
}
59+
60+
public func mapOptional<A, B>(_ f: @escaping (A) -> B?) -> ([A]) -> [B] {
61+
return { xs in
62+
xs.flatMap(f)
63+
}
64+
}
65+
66+
public func replicate<A>(_ n: Int) -> (A) -> [A] {
67+
return { a in (1...n).map(const(a)) }
68+
}

Sources/Prelude/Choice.swift

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
func left<A, B, C>(_ a2b: @escaping (A) -> B) -> (Either<A, C>) -> Either<B, C> {
2+
return { either in
3+
switch either {
4+
case let .left(a):
5+
return .left(a2b(a))
6+
case let .right(c):
7+
return .right(c)
8+
}
9+
}
10+
}
11+
12+
func right<A, B, C>(_ b2c: @escaping (B) -> C) -> (Either<A, B>) -> Either<A, C> {
13+
return { either in
14+
switch either {
15+
case let .left(a):
16+
return .left(a)
17+
case let .right(c):
18+
return .right(b2c(c))
19+
}
20+
}
21+
}

Sources/Prelude/Either.swift

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
public enum Either<L, R> {
2+
case left(L)
3+
case right(R)
4+
}
5+
6+
extension Either {
7+
public var left: L? {
8+
switch self {
9+
case let .left(x):
10+
return x
11+
case .right:
12+
return nil
13+
}
14+
}
15+
16+
public var right: R? {
17+
switch self {
18+
case .left:
19+
return nil
20+
case let .right(x):
21+
return x
22+
}
23+
}
24+
}
25+
26+
public func rights<L, R>(_ xs: [Either<L, R>]) -> [R] {
27+
return xs |> mapOptional { $0.right }
28+
}

Sources/Prelude/Function.swift

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
public func id<A>(_ a: A) -> A {
2+
return a
3+
}
4+
5+
public func <<< <A, B, C>(_ b2c: @escaping (B) -> C, _ a2b: @escaping (A) -> B) -> (A) -> C {
6+
return { a in b2c(a2b(a)) }
7+
}
8+
9+
public func >>> <A, B, C>(_ a2b: @escaping (A) -> B, _ b2c: @escaping (B) -> C) -> (A) -> C {
10+
return { a in b2c(a2b(a)) }
11+
}
12+
13+
public func const<A, B>(_ a: A) -> (B) -> A {
14+
return { _ in a }
15+
}
16+
17+
public func <| <A, B> (f: (A) -> B, a: A) -> B {
18+
return f(a)
19+
}
20+
21+
public func |> <A, B> (a: A, f: (A) -> B) -> B {
22+
return f(a)
23+
}

Sources/Prelude/Monoid.swift

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
public protocol Monoid: Semigroup {
2+
static var e: Self { get }
3+
}
4+
5+
public func concat<M: Monoid>(_ xs: [M]) -> M {
6+
return xs.reduce(M.e, <>)
7+
}
8+
9+
extension String: Monoid {
10+
public static let e = ""
11+
12+
public static func <>(lhs: String, rhs: String) -> String {
13+
return lhs + rhs
14+
}
15+
}
16+
17+
extension Array: Monoid {
18+
public static var e: Array { return [] }
19+
20+
public static func <>(lhs: Array, rhs: Array) -> Array {
21+
return lhs + rhs
22+
}
23+
}
24+
25+
public func joined<M: Monoid>(_ s: M) -> ([M]) -> M {
26+
return { xs in
27+
if let head = xs.first {
28+
return xs.dropFirst().reduce(head) { accum, x in accum <> s <> x }
29+
}
30+
return .e
31+
}
32+
}

Sources/Prelude/Operators.swift

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
precedencegroup HashRocket {
2+
associativity: left
3+
higherThan: Semigroup
4+
}
5+
infix operator =>: HashRocket
6+
7+
precedencegroup Alt {
8+
associativity: left
9+
}
10+
11+
precedencegroup Apply {
12+
higherThan: Alt
13+
associativity: left
14+
}
15+
16+
precedencegroup Functor {
17+
higherThan: Apply
18+
associativity: left
19+
}
20+
21+
precedencegroup FunctionApplication {
22+
associativity: left
23+
higherThan: Semigroup
24+
}
25+
26+
precedencegroup FunctionApplicationFlipped {
27+
associativity: left
28+
higherThan: FunctionApplication
29+
}
30+
31+
precedencegroup Semigroup {
32+
associativity: right
33+
higherThan: AdditionPrecedence
34+
}
35+
36+
precedencegroup FunctionComposition {
37+
associativity: right
38+
}
39+
40+
precedencegroup MonadicBind {
41+
associativity: right
42+
}
43+
44+
45+
infix operator <<<: FunctionComposition
46+
infix operator >>>: FunctionComposition
47+
infix operator <|: FunctionApplication
48+
infix operator |>: FunctionApplicationFlipped
49+
infix operator <|>: Alt
50+
infix operator <*>: Apply
51+
infix operator <*: Apply
52+
infix operator *>: Apply
53+
54+
infix operator <¢>: Functor
55+
infix operator : Functor
56+
57+
infix operator <>: Semigroup
58+
prefix operator <>
59+
postfix operator <>
60+
61+
infix operator >>-: MonadicBind

Sources/Prelude/Optional.swift

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public func coalesce<A>(with `default`: A) -> (A?) -> A {
2+
return { x in x ?? `default` }
3+
}

0 commit comments

Comments
 (0)