Skip to content

Instantly share code, notes, and snippets.

@olenhad
Created January 22, 2016 10:45
Show Gist options
  • Save olenhad/ad7b1845f39745cec5b1 to your computer and use it in GitHub Desktop.
Save olenhad/ad7b1845f39745cec5b1 to your computer and use it in GitHub Desktop.
//: 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