Created
February 13, 2017 09:30
-
-
Save ukitaka/597041c1ba82e3f0d57f3dbb88d4f907 to your computer and use it in GitHub Desktop.
自作の型でもFunctorであれば無理やりCovariantっぽく振舞わせることができる
This file contains hidden or 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
enum Maybe<A> { | |
case some(A) | |
case none | |
func map<B>(_ f: (A) -> B) -> Maybe<B> { | |
switch self { | |
case .some(let a): | |
return .some(f(a)) | |
case .none: | |
return .none | |
} | |
} | |
} | |
protocol Animal { } | |
struct Dog: Animal { } | |
let maybeDog: Maybe<Dog> = .some(Dog()) | |
// NG: cannot assign Maybe<Dog> to Maybe<Animal> | |
// let maybeAnimal: Maybe<Animal> = maybeDog | |
// NG: cannot convert Maybe<Dog> to Maybe<Animal> | |
// let maybeAnimal: Maybe<Animal> = maybeDog as! Maybe<Animal> | |
func id<A>(_ a: A) -> A { | |
return a | |
} | |
// workaround | |
extension Maybe where A: Animal { | |
var covariant: Maybe<Animal> { | |
return map(id) | |
} | |
} | |
// OK | |
let maybeAnimal: Maybe<Animal> = maybeDog.covariant | |
func test() -> Maybe<Animal> { | |
return maybeDog.covariant // OK | |
} |
extension ObservableType where E: Animal {
var covariant: Observable<Animal> {
return self.map(id)
}
}
// NG
//let animal: Observable<Animal> = Observable<Dog>.empty()
// OK
let animal: Observable<Animal> = Observable<Dog>.empty().covariant
class Shape {
var name: String {
return "Shape"
}
}
class Rectangle: Shape {
override var name: String {
return "Rectangle"
}
}
class Square: Rectangle {
override var name: String {
return "Square"
}
}
extension Maybe where A: Shape {
var covariant: Maybe<Shape> {
return map(id)
}
}
extension Maybe where A: Rectangle {
var covariant: Maybe<Rectangle> {
return map(id)
}
}
let maybeSquare: Maybe<Square> = .some(Square())
let maybeRectAngle: Maybe<Rectangle> = maybeSquare.covariant
let maybeShape: Maybe<Shape> = maybeSquare.covariant
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
もちろん組み込みの型ならこんなことしなくてもCovariantなので問題ない