-
-
Save rnapier/5a84f65886e1ee40f62e to your computer and use it in GitHub Desktop.
Quick notes on higher-kinded 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
import Foundation | |
// Say we have a function | |
func firstInt(xs: [Int]) -> Int { | |
return xs[0] | |
} | |
// Of course we can call it | |
let a = [1,2,3] | |
firstInt(a) | |
// And of course we can assign it to a variable, and call that. | |
// Functions are first class. But....dependes on their type. | |
let fi = firstInt | |
fi(a) | |
// Say we have a generic function | |
func firstT<T>(xs: [T]) -> T { | |
return xs[0] | |
} | |
firstT(a) | |
// Shouldn't we be able to assign *it* to a variable? It's a function, right? | |
// let ft = firstT // "Argument for generic parameter 'T' could not be inferred" | |
// So we can't do this: | |
// ft([1,2,3]) | |
// There's no way to talk about the type <T>([T])->T. | |
// It's not a real type in Swift. This is frustrating because it means | |
// that closures and functions are not interchangable. | |
// In more general terms, an Int is concrete type, and is completely supported | |
// in Swift. Array<Int> is also a concrete type. But "Array" is a first-order | |
// type, and you can't do everything with it. "Mappable" is an even higher-order type, | |
// and we can't even talk about it in Swift today. Here's what it might look like if | |
// we could: | |
//protocol Mappable<A, Container<_>> { | |
// func map<B>(f: (A)->B) -> Container<B> | |
//} | |
// The magic is that "Container<_>" which says "Mappable is specialized | |
// by a type that it *itself* parameterizeable." So Container might be | |
// Array, or Dictionary, or Set, or anything. That means map needs to be | |
// able to construct the *type* of its return, not just the instance of | |
// its return. So we can't create functions that take an arbitrary Functor | |
// in Swift. | |
// I also cannot make a collection of generic closures, which is one piece of a broader Swift | |
// bifurcation of "methods" and "data." This crops up other places like | |
// the fact that properties are not functions. | |
// In principle, struct "methods" could be nothing more than properties. | |
// In Swift, these three structs have different shapes, and that's awkward | |
// and inflexible. | |
struct PropertyThing { | |
let x: Int = 42 | |
} | |
struct FunctionThing { | |
func x() -> Int { return 42 } | |
} | |
struct ClosureThing { | |
let x = { return 42 } | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment