Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.84 KB | None | 0 0
  1. // Playground - noun: a place where people can play
  2.  
  3. import UIKit
  4. import CoreGraphics
  5.  
  6. public enum Result<T> {
  7. case Success(@autoclosure () -> T)
  8. case Failure(String)
  9.  
  10. init(_ value:T) {
  11. self = .Success(value)
  12. }
  13. }
  14.  
  15. extension Result {
  16. public func bind<U>(f: T -> Result<U>) -> Result<U> {
  17. switch self {
  18. case let .Success(value):
  19. return f(value())
  20. case let .Failure(error):
  21. return .Failure(error)
  22. }
  23. }
  24.  
  25. public func fmap<U>(f: T->U) -> Result<U> {
  26. switch self {
  27. case let .Success(value):
  28. return .Success(f(value()))
  29. case let .Failure(error):
  30. return .Failure(error)
  31. }
  32. }
  33.  
  34. public func forceUnwrap() -> T {
  35. switch self {
  36. case let .Success(value):
  37. return value()
  38. case let .Failure:
  39. assertionFailure("You force unwrapped \(self), which was not a Result.Success")
  40. }
  41. }
  42. }
  43.  
  44. infix operator |> { precedence 50 associativity left }
  45.  
  46. // MARK: Curry
  47.  
  48. public func curry<A, B, Z>(f: (A, B) -> Z) -> A -> B -> Z {
  49. return { a in { b in f(a, b) } }
  50. }
  51.  
  52. public func curry<A, B, C, Z>(f: (A, B, C) -> Z) -> A -> B -> C -> Z {
  53. return { a in { b in { c in f(a, b, c) } } }
  54. }
  55.  
  56. public func curry<A, B, C, D, Z>(f: (A, B, C, D) -> Z) -> A -> B -> C -> D -> Z {
  57. return { a in { b in { c in { d in f(a, b, c, d) } } } }
  58. }
  59.  
  60. public func curry<A, B, C, D, E, Z>(f: (A, B, C, D, E) -> Z) -> A -> B -> C -> D -> E -> Z {
  61. return { a in { b in { c in { d in { e in f(a, b, c, d, e) } } } } }
  62. }
  63.  
  64. // MARK: Reverse Curry
  65.  
  66. public func reverseCurry<A, B, Z>(f: (A, B) -> Z) -> B -> A -> Z {
  67. return { b in { a in f(a, b) } }
  68. }
  69.  
  70. public func reverseCurry<A, B, C, Z>(f: (A, B, C) -> Z) -> C -> B -> A -> Z {
  71. return {c in { b in { a in f(a, b, c) } } }
  72. }
  73.  
  74. public func reverseCurry<A, B, C, D, Z>(f: (A, B, C, D) -> Z) -> D -> C -> B -> A -> Z {
  75. return { d in { c in { b in { a in f(a, b, c, d) } } } }
  76. }
  77.  
  78. public func reverseCurry<A, B, C, D, E, Z>(f: (A, B, C, D, E) -> Z) -> E -> D -> C -> B -> A -> Z {
  79. return { e in { d in { c in { b in { a in f(a, b, c, d, e) } } } } }
  80. }
  81.  
  82. // MARK: Pipeline
  83.  
  84. public func |> <A,Z>(lhs: A, rhs: A -> Z) -> Z {
  85. return rhs(lhs)
  86. }
  87.  
  88. public func |> <A,B,Z>(lhs: A, rhs: ((A, B) -> Z, B)) -> Z {
  89. return rhs.0(lhs, rhs.1)
  90. }
  91.  
  92. public func |> <A,B,C,Z>(lhs: A, rhs: (((A, B, C) -> Z), B, C)) -> Z {
  93. return rhs.0(lhs, rhs.1, rhs.2)
  94. }
  95.  
  96. // MARK: Optional Pipeline
  97.  
  98. public func |> <A, Z>(lhs: A?, rhs: A -> Z) -> Z? {
  99. return map(lhs, rhs)
  100. }
  101.  
  102. public func |> <A, B, Z>(lhs: A?, rhs: ((A, B) -> Z, B)) -> Z? {
  103. return map(lhs, reverseCurry(rhs.0)(rhs.1))
  104. }
  105.  
  106. public func |> <A,B,C,Z>(lhs: A?, rhs: (((A, B, C) -> Z), B, C)) -> Z? {
  107. return map(lhs, reverseCurry(rhs.0)(rhs.2)(rhs.1))
  108. }
  109.  
  110. // MARK: Result Pipeline
  111.  
  112. public func |> <A,Z>(lhs: Result<A>, rhs: A -> Z) -> Result<Z> {
  113. return lhs.fmap(rhs)
  114. }
  115.  
  116. public func |> <A,B,Z>(lhs: Result<A>, rhs: ((A, B) -> Z, B)) -> Result<Z> {
  117. return lhs.fmap(reverseCurry(rhs.0)(rhs.1))
  118. }
  119.  
  120. public func |> <A,B,C,Z>(lhs: Result<A>, rhs: (((A, B, C) -> Z), B, C)) -> Result<Z> {
  121. return lhs.fmap(reverseCurry(rhs.0)(rhs.2)(rhs.1))
  122. }
  123.  
  124. // MARK: Examples
  125.  
  126. func increment(int: Int) -> Int {
  127. return int + 1
  128. }
  129.  
  130.  
  131. 2 |> increment
  132.  
  133. // clear, concise, and functional, but only works on arrays.
  134. // does not generalize to Sequence
  135. let example1 = [1,2,3,4,5].filter({$0 % 2 == 0}).map({$0 * 3}).reduce(0, +)
  136. example1
  137.  
  138. // this is dirtier than example1, but generalized to Sequence
  139. let example2 = reduce(map(filter([1,2,3,4,5], {$0 % 2 == 0}), {$0 * 3}), 0, +)
  140. example2
  141.  
  142. // works on sequences and clean
  143. let example3 = [1,2,3,4,5]
  144. |> (filter, {$0 % 2 == 0})
  145. |> (map, {$0 * 3})
  146. |> (reduce, 0, +)
  147. example3
  148.  
  149. // Optional examples
  150.  
  151. let elements = [2, 4, 6, 8, 10]
  152. let isEvenIndex = find(elements, 6) |> { $0 % 2 == 0} // "Found 6 at index 2"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement