Last active
June 10, 2022 05:59
-
-
Save ikhoon/9726c56ea2bd2785eb47a97e568d0327 to your computer and use it in GitHub Desktop.
왜 함수의 input은 반공변성인가?
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
// https://twitter.github.io/scala_school/type-basics.html | |
// 트위터 스칼라 스쿨에 나오는 자료구조를 활용해보겠다. | |
class Animal { val sound = "rustle" } | |
class Bird extends Animal { override val sound = "call" } | |
class Chicken extends Bird { override val sound = "cluck" } | |
class Duck extends Bird { override val sound = "duck" } | |
def foo(tweet: Bird => String) = { | |
tweet(new Bird) | |
tweet(new Duck) | |
} | |
// tweet이란 함수에 f란 인자를 받았는다. | |
// f는 Bird를 받아서 String을 반환하는 함수이다. | |
// 그러며 f에는 어떤 함수를 대입할수 있을까? | |
def bar(c: Chicken) : String = c.sound | |
def baz(b: Bird): String = b.sound | |
def quz(a: Animal): String = a.sound | |
// 위의 3개의 함수중에 | |
// 단 2개만이 foo 함수에 대입할수 있다. | |
// baz 와 quz이다 | |
// 이유는 11번째 bird에 duck을 대입하는건 아무런 문제가 없어야 하기 때문이다. | |
// 그럴러면 치환의 법칙 상위타입에 하위 타입을 대입할수 있어야 한다. | |
// 즉 foo 함수 내부에서 Bird 보다 하위 타입을 대입을 하려면 | |
// tweet 함수에는 bird 보다 상위 타입이 인자로 들어와야지 대입을 할수 있기 때문이다. | |
foo(baz) // 됨 | |
foo(quz) // 됨 | |
foo(bar) // 안됨, foo 함수 안에서 bird에 duck을 대입하는데, chicken과 duck은 상하위 타입 관계가 아니다. | |
// 대입은 같은 타입이거나, 하위 타입이 상위 타입에만 할수 있다. 이 원칙은 변하지 않는다. | |
// tweet: Bird => String 에 대입이 가능한 baz는 Bird => String의 타입을 가지는 같은 타입이다. | |
// 그러면 quz는 Animal => String 이다. Animal은 Bird의 상위 타입이지만 반 공변성을 가지고 | |
// Animal => String 은 Bird => String의 하위 타입이 된다. | |
// 참고로 함수의 타입 시그니쳐는 | |
trait Function[-T, +R] | |
// 인자는 반공변, 반환값은 공변이다. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👍 💯 🥇