Skip to content

Instantly share code, notes, and snippets.

View rnapier's full-sized avatar

Rob Napier rnapier

View GitHub Profile
@rnapier
rnapier / gist:0f5611d0bf89a9645713
Last active August 29, 2015 14:05
Version 3 of Functional Wish Fulfillment
//
// Version 3 of pagesFromData from Functional Wish Fulfillment
// http://robnapier.net/functional-wish-fulfillment
//
import Foundation
func pagesFromData(data: NSData) -> Result<[Page]> {
return continueWith(asJSON(data)) {
continueWith(asJSONArray($0)) {
@rnapier
rnapier / Curryinate.swift
Last active August 29, 2015 14:05
Curry and flip with ~~ postfixing. I wonder if this is a good idea…
// Based on https://gist.github.com/kristopherjohnson/adde22d2c53adfb756a1
// Warning, this is insanely slow to compile in Beta6 (can take several minutes)
// Remove some of the |> lines to speed things up
// For more on |>, see http://undefinedvalue.com/2014/07/13/fs-pipe-forward-operator-swift
infix operator |> { precedence 50 associativity left }
// "x |> f" is equivalent to "f(x)"
public func |> <T,U>(lhs: T, rhs: T -> U) -> U {
return rhs(lhs)
@rnapier
rnapier / gist:7321b964497cbc779b7b
Last active August 29, 2015 14:05
Generics do not compose (is that the right way to think about it?)
// Generics do not compose
// The generic f()
func f<T>(x: T) -> T { return g(x) }
// The every-day g() that f() calls
func g<T>(x: T) -> T {
return x
}
@rnapier
rnapier / gist:2c7eb3be64bae0033ce7
Last active August 29, 2015 14:05
And I immediately run into the problem from yesterday. Functions don't specialize the way you'd think they would.
import Foundation
// Standard Result and Beta6-workaround Box
enum Result<A> {
case Success(Box<A>)
case Failure(NSError)
}
final class Box<T> {
let unbox: T
@rnapier
rnapier / imagePageTitlesForPage.swift
Last active August 29, 2015 14:05
Incredibly powerful IMO, but how to make less scary?
// Page has title and identifier propeties
// >>== is >>= (flatMap)
// Goal is to convert a Page into a future, possibly failing, list of titles of image pages
// (I'm contemplating later to defining a Promise<T> as a Future<Result<T>>)
// If there are no images, then we should return [], not an error (even though the "images" key will be missing)
// But we should return an error if parsing otherwise fails (including missing keys)
// How much information/education does an incoming dev need to be able to read this and feel
// feel comfortable doing minor adjustments to it if the API changed?
@rnapier
rnapier / gist:5d946bb46a9f78423d6a
Last active August 29, 2015 14:06
Version 1 of Flattenin your mappenin
//
// Version 1 of pagesFromData from Flat All The Things
// http://robnapier.net/flatmap
//
import Foundation
func pagesFromData(data: NSData) -> Result<[Page]> {
return asJSON(data)
.flatMap(asJSONArray)
@rnapier
rnapier / gist:f26e97cb3ceda62e92ff
Last active August 29, 2015 14:06
You can attach associated objects onto numeric constants.
// Fun fact. You can attach associated objects onto numeric constants.
// I feel this is probably a horrible idea.
import Foundation
func ten() -> Int { return 10 }
var MyKey: Character = "0"
objc_setAssociatedObject(10, &MyKey, "I'm a value!", objc_AssociationPolicy(OBJC_ASSOCIATION_COPY))
println(objc_getAssociatedObject(10, &MyKey)) // yes
@rnapier
rnapier / result.swift
Last active August 29, 2015 14:06
The ever-important Result type (without methods)
enum Result<A> {
case Success(Box<A>)
case Failure(NSError)
}
// Due to current swift limitations, we have to include this Box in Result.
// Swift cannot handle an enum with multiple associated data (A, NSError) where one is of unknown size (A)
final class Box<T> {
let unbox: T
init(_ value: T) { self.unbox = value }
@rnapier
rnapier / gist:e0d91580d613fb21a52b
Created September 6, 2014 15:57
Customer example from Flattenin' your mappenin'
struct Customer {
let name: String
let emails: [String]
}
let customers = [
Customer(name: "Alice", emails: ["alice@example.com"]),
Customer(name: "Bob", emails: ["bob@example.org", "bobby@home.example"])]
let names = customers.map { $0.name }
@rnapier
rnapier / FlatMapProof.swift
Created September 7, 2014 13:46
Proof: flatMap<Result> and continueWith are the the same function
// Claim: flatMap<Result> and continueWith are the the same function
//
// Begin with flatMap and its dependencies
//
func flatMap<T,U>(x: Result<T>, f: T -> Result<U>) -> Result<U> {
return flatten(map(x, f))
}
func map<T, U>(x: Result<T>, f: T -> U) -> Result<U> {