Skip to content

Instantly share code, notes, and snippets.

@ikhoon
Last active June 10, 2022 05:59
Show Gist options
  • Save ikhoon/9726c56ea2bd2785eb47a97e568d0327 to your computer and use it in GitHub Desktop.
Save ikhoon/9726c56ea2bd2785eb47a97e568d0327 to your computer and use it in GitHub Desktop.
왜 함수의 input은 반공변성인가?
// 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]
// 인자는 반공변, 반환값은 공변이다.
@jiyeonseo
Copy link

👍 💯 🥇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment