Created
January 22, 2016 10:45
-
-
Save olenhad/ad7b1845f39745cec5b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
var str = "Hello, playground" | |
enum Maybe<T> { | |
case Nothing | |
case Just(T) | |
} | |
enum Either<T> { | |
case Result(T) | |
case NSError | |
} | |
extension Maybe { | |
func map<U>(f: T -> U) -> Maybe<U> { | |
switch self { | |
case .Just(let t): return .Just(f(t)) | |
case .Nothing: return .Nothing | |
} | |
} | |
} | |
infix operator <^> { associativity left } | |
func <^><T, U>(f: T -> U, a: Maybe<T>) -> Maybe<U> { | |
return a.map(f) | |
} | |
func <^><T, U>(f: T -> U, a: T?) -> U? { | |
return a.map(f) | |
} | |
let length = Maybe.Just("Vincent").map {$0.characters.count} | |
length | |
extension Maybe { | |
func apply<U>(f: Maybe<T -> U>) -> Maybe<U> { | |
switch f { | |
case .Just(let someF): return self.map(someF) | |
case .Nothing: return .Nothing | |
} | |
} | |
} | |
let res = Maybe.Just(2).apply(Maybe.Just({$0 + 3})) | |
res | |
infix operator <*> { associativity left } | |
func <*><T, U>(f: Maybe<T -> U>, a: Maybe<T>) -> Maybe<U> { | |
return a.apply(f) | |
} | |
func curredAdd1(a: Int) -> (Int -> Int){ | |
return {b in return b + a} | |
} | |
curredAdd1(1) | |
Maybe.Just(2).map(curredAdd1(1)) | |
curredAdd1(1) <^> .Just(2) | |
func curriedAdd(a: Int)(b: Int) -> Int { | |
return a + b | |
} | |
(curriedAdd <^> .Just(1)) | |
(curriedAdd <^> .Just(1)) <*> .Just(2) | |
// Real World Example | |
extension Optional { | |
func apply<U>(f: (Wrapped -> U)?) -> U? { | |
switch f { | |
case .Some(let someF): return self.map(someF) | |
case .None: return .None | |
} | |
} | |
} | |
func <*><T, U>(f: (T -> U)?, a: T?) -> U? { | |
return a.apply(f) | |
} | |
struct User { | |
let name: String | |
let age: Int | |
static func user(name: String)(age: Int) -> User { | |
return User(name: name, age: age) | |
} | |
static func user(name: String)(age: Int) -> User { | |
return User(name: name, age: age) | |
} | |
} | |
let data = ["name": 1, "age": 16] | |
func asString(a: Any?) -> String? { | |
if let s = a as? String { | |
return Optional(s) | |
} | |
return nil | |
} | |
func asInt(a: Any?) -> Int? { | |
if let s = a as? Int { | |
return Optional(s) | |
} | |
return nil | |
} | |
(User.user <^> .Just("Vincent")) <*> .Just(12) | |
let u = User.user <^> | |
asString(data["name"]) <*> | |
asInt(data["age"]) | |
User.user(asString, asInt) | |
func half(a: Int) -> Int? { | |
return a % 2 == 0 ? a / 2 : nil | |
} | |
Optional(5).flatMap(half) | |
Optional(4).flatMap(half) | |
extension Maybe { | |
func flatMap<U>(f: T -> Maybe<U>) -> Maybe<U> { | |
switch self { | |
case .Just(let v): return f(v) | |
case .Nothing: return .Nothing | |
} | |
} | |
} | |
func fetchAndrew() -> User? { | |
return User(name: "Andrew ZenMaster", age: 99) | |
} | |
func fetchCarolyn() -> User? { | |
return User(name: "Carolyn San", age: 24) | |
} | |
func rankPartnersForVincent(user: User) -> Int? { | |
if (user.age < 99) { | |
return nil | |
} | |
return 1 | |
} | |
fetchAndrew().flatMap(rankPartnersForVincent) | |
fetchCarolyn().flatMap(rankPartnersForVincent) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment