Last active
December 8, 2015 19:46
-
-
Save adamkuipers/bb7bdb9cc425de8905c7 to your computer and use it in GitHub Desktop.
Higher-kinded types encoded as path-dependent types
This file contains 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
// Based off of https://gist.github.com/runarorama/33986541f0f1ddf4a3c7 | |
protocol λ { | |
typealias α | |
} | |
struct K<L: λ>: λ { | |
typealias α = L.α | |
} | |
protocol Each: λ { | |
typealias α: λ | |
typealias A = K<α>.α | |
static func foreach(x: α, f: A -> Void) | |
} | |
extension Optional: λ { | |
typealias α = Wrapped | |
} | |
struct OptionalEach<Wrapped>: Each { | |
typealias α = Optional<Wrapped> | |
static func foreach(x: α, f: Wrapped -> Void) { | |
if let e = x { | |
f(e) | |
} | |
} | |
} | |
extension Array: λ { | |
typealias α = Element | |
} | |
struct ArrayEach<Element>: Each { | |
typealias α = Array<Element> | |
static func foreach(x: α, f: Element -> Void) { | |
x.forEach(f) | |
} | |
} | |
ArrayEach<Int>.foreach([1,2,3]) { print($0) } | |
OptionalEach<String>.foreach("a") { print($0) } | |
OptionalEach<String>.foreach(nil) { print($0) } | |
protocol HasEach: λ { | |
typealias E: Each | |
} | |
extension Array: HasEach { | |
typealias E = ArrayEach<Element> | |
} | |
// Can't figure out how to get the typeclass to resolve for global functions. | |
func foreach<X: HasEach>(x: X, f: X.α -> Void) { | |
X.E.foreach(x, f: f) | |
} | |
// Compiler Error: | |
// error: cannot convert value of type 'X.α -> Void' to expected argument type '_ -> Void' | |
// X.E.foreach(x, f: f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment