Skip to content

Instantly share code, notes, and snippets.

@pteasima
Last active January 17, 2019 07:29
Show Gist options
  • Save pteasima/84216042e8fec5f1cdd02bc350ef71d4 to your computer and use it in GitHub Desktop.
Save pteasima/84216042e8fec5f1cdd02bc350ef71d4 to your computer and use it in GitHub Desktop.
HKTs
protocol Functor {
associatedtype Tag
associatedtype E //Element or _Element clashes on Dictionary :(
}
struct Functoring<F: Functor> {
let _map: (F, (F.E) -> Any) -> Any
func map<FB: Functor>(_ functor: F, transform: (F.E) -> FB.E) -> FB where F.Tag == FB.Tag {
return _map(functor, transform) as! FB
}
}
enum ArrayTag {}
extension Array: Functor {
typealias Tag = ArrayTag
typealias E = Element
}
enum DictionaryTag {}
extension Dictionary: Functor {
typealias Tag = DictionaryTag
typealias E = Value
}
func functoring<Element>() -> Functoring<[Element]> { return .init { $0.map($1) } }
func functoring<Key, Element>() -> Functoring<[Key: Element]> { return .init { $0.mapValues($1) }}
let array: [Int] = functoring().map(["foo"]) { $0.count }
let dict: [String: Int] = functoring().map(["bar": "foo"]) { $0.count }
let fail: [String: Int] = functoring().map(["foo"]) { $0.count }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment