Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Playground - noun: a place where people can play
- import UIKit
- import CoreGraphics
- public enum Result<T> {
- case Success(@autoclosure () -> T)
- case Failure(String)
- init(_ value:T) {
- self = .Success(value)
- }
- }
- extension Result {
- public func bind<U>(f: T -> Result<U>) -> Result<U> {
- switch self {
- case let .Success(value):
- return f(value())
- case let .Failure(error):
- return .Failure(error)
- }
- }
- public func fmap<U>(f: T->U) -> Result<U> {
- switch self {
- case let .Success(value):
- return .Success(f(value()))
- case let .Failure(error):
- return .Failure(error)
- }
- }
- public func forceUnwrap() -> T {
- switch self {
- case let .Success(value):
- return value()
- case let .Failure:
- assertionFailure("You force unwrapped \(self), which was not a Result.Success")
- }
- }
- }
- infix operator |> { precedence 50 associativity left }
- // MARK: Curry
- public func curry<A, B, Z>(f: (A, B) -> Z) -> A -> B -> Z {
- return { a in { b in f(a, b) } }
- }
- public func curry<A, B, C, Z>(f: (A, B, C) -> Z) -> A -> B -> C -> Z {
- return { a in { b in { c in f(a, b, c) } } }
- }
- public func curry<A, B, C, D, Z>(f: (A, B, C, D) -> Z) -> A -> B -> C -> D -> Z {
- return { a in { b in { c in { d in f(a, b, c, d) } } } }
- }
- public func curry<A, B, C, D, E, Z>(f: (A, B, C, D, E) -> Z) -> A -> B -> C -> D -> E -> Z {
- return { a in { b in { c in { d in { e in f(a, b, c, d, e) } } } } }
- }
- // MARK: Reverse Curry
- public func reverseCurry<A, B, Z>(f: (A, B) -> Z) -> B -> A -> Z {
- return { b in { a in f(a, b) } }
- }
- public func reverseCurry<A, B, C, Z>(f: (A, B, C) -> Z) -> C -> B -> A -> Z {
- return {c in { b in { a in f(a, b, c) } } }
- }
- public func reverseCurry<A, B, C, D, Z>(f: (A, B, C, D) -> Z) -> D -> C -> B -> A -> Z {
- return { d in { c in { b in { a in f(a, b, c, d) } } } }
- }
- public func reverseCurry<A, B, C, D, E, Z>(f: (A, B, C, D, E) -> Z) -> E -> D -> C -> B -> A -> Z {
- return { e in { d in { c in { b in { a in f(a, b, c, d, e) } } } } }
- }
- // MARK: Pipeline
- public func |> <A,Z>(lhs: A, rhs: A -> Z) -> Z {
- return rhs(lhs)
- }
- public func |> <A,B,Z>(lhs: A, rhs: ((A, B) -> Z, B)) -> Z {
- return rhs.0(lhs, rhs.1)
- }
- public func |> <A,B,C,Z>(lhs: A, rhs: (((A, B, C) -> Z), B, C)) -> Z {
- return rhs.0(lhs, rhs.1, rhs.2)
- }
- // MARK: Optional Pipeline
- public func |> <A, Z>(lhs: A?, rhs: A -> Z) -> Z? {
- return map(lhs, rhs)
- }
- public func |> <A, B, Z>(lhs: A?, rhs: ((A, B) -> Z, B)) -> Z? {
- return map(lhs, reverseCurry(rhs.0)(rhs.1))
- }
- public func |> <A,B,C,Z>(lhs: A?, rhs: (((A, B, C) -> Z), B, C)) -> Z? {
- return map(lhs, reverseCurry(rhs.0)(rhs.2)(rhs.1))
- }
- // MARK: Result Pipeline
- public func |> <A,Z>(lhs: Result<A>, rhs: A -> Z) -> Result<Z> {
- return lhs.fmap(rhs)
- }
- public func |> <A,B,Z>(lhs: Result<A>, rhs: ((A, B) -> Z, B)) -> Result<Z> {
- return lhs.fmap(reverseCurry(rhs.0)(rhs.1))
- }
- public func |> <A,B,C,Z>(lhs: Result<A>, rhs: (((A, B, C) -> Z), B, C)) -> Result<Z> {
- return lhs.fmap(reverseCurry(rhs.0)(rhs.2)(rhs.1))
- }
- // MARK: Examples
- func increment(int: Int) -> Int {
- return int + 1
- }
- 2 |> increment
- // clear, concise, and functional, but only works on arrays.
- // does not generalize to Sequence
- let example1 = [1,2,3,4,5].filter({$0 % 2 == 0}).map({$0 * 3}).reduce(0, +)
- example1
- // this is dirtier than example1, but generalized to Sequence
- let example2 = reduce(map(filter([1,2,3,4,5], {$0 % 2 == 0}), {$0 * 3}), 0, +)
- example2
- // works on sequences and clean
- let example3 = [1,2,3,4,5]
- |> (filter, {$0 % 2 == 0})
- |> (map, {$0 * 3})
- |> (reduce, 0, +)
- example3
- // Optional examples
- let elements = [2, 4, 6, 8, 10]
- let isEvenIndex = find(elements, 6) |> { $0 % 2 == 0} // "Found 6 at index 2"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement