Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3장 매개변수에 의한 다형성 #1069

Open
Tracked by #1046
jongfeel opened this issue Jan 28, 2025 · 0 comments
Open
Tracked by #1046

3장 매개변수에 의한 다형성 #1069

jongfeel opened this issue Jan 28, 2025 · 0 comments

Comments

@jongfeel
Copy link
Owner

jongfeel commented Jan 28, 2025

3장 매개변수에 의한 다형성

과일 고르기 대화

  • 사과자동선택기계: 사과 두 개 중 무거운 사과를 사과 매대에 내려놓음
  • 복숭아자동선택기계, 바나나자동선택기계, ...
  • 자동신택기계: 같은 과일 끼리는 되지만 다른 과일 끼리는 섞임
  • 완전똑똑자동선택기계: 뭘 넣을 건지 기계한테 먼저 알려주고 과일을 넣음

3.1 제네릭 함수

매개변수에 의한 다형성(parametric polymorphism)은 타입 매개변수를 통해 다형성을 만드는 기능이다.
제네릭스(generics)라고 부른다.

서브타입에 의한 다형성과 최대 타입을 모두 제공하는 언어라면
함수에 아무 값이나 받도록 해서 구현할 수 있다.

예) Any choose(Any v1, Any v2)

문제는 타입 검사를 통과하지 못하는 연산 (string의 contains() 메서드나, int의 +, * 와 같은 연산)이 생긴다.

매개변수에 의한 다형성을 사용한다면 아래와 같이 구현 가능하다.

예) T choose< T >(T v1, T v2)

제네릭 함수를 정의할 때는 타입 검사기가 제네릭 함수 정의를 검사하는 방식을 이해해야 한다.
아무 타입이나 나타낼 수 있다고 가정한다.
그리고 타입 검사를 통과한다.
하지만 T 타입에 따라 이후 연산을 할 수 있는지 아닌지는 나중에 판단한다.

제네릭 메서드

제네릭 메서드는 클래스 안에 정의된다는 점만 제외하면 제네릭 함수와 같다.

타입 인자 추론

choose< Int >(1, 2) 와 같이 번거롭게 작성하는 것이 아닌
chooose(1, 2)와 같은 형태로 코드 작성이 가능하다.
이는 타입 검사기에서는 쉬운 일이기 때문에 그렇다.

때로 코드가 복잡해지만 타입 검사기가 타입 인자 추론에 실패할 수도 있다.
그래서 타입 인자 추론이 언제나 내가 원하는 대로 되지 않는다는 사실을 기억해야 한다.

힌들리-밀너 타입 추론

제네릭 함수를 정의할 때에 타입 추론을 하는 방식을 힌들리-밀너 타입 추론이라고 한다. (Hindley-Milner type inference)
이는 타입 매개변수를 쓰지 않아도 함수가 자동으로 제네릭 함수가 된다는 뜻이다.
다른 용어로 렛 다형성(let polymorphism)이라는 용어를 쓰기도 하는데 어캐멀에서 함수를 정의할 대 사용하는 키워드인 let에서 왔기 때문이다.
이 추론은 매개변수 타입과 결과 타입도 추론하기 때문에 다음과 같이 함수를 정의할 수 있다.

예) function choose(v1, v2)

그러면 타입 검사기는 다음 처럼 해석한다.

예) T choose< T >(T v1, T v2)

힌들리 밀너 타입 추론은 굉장히 똑똑해서 제네릭 함수로 만들어야 할 때와 그렇지 않을 때를 구분한다.

아래와 같은 함수를 정의한다면 타입 검사기는 이를 제네릭 함수로 만들지 않는다는 뜻이다.

function mult(v1, v1, v3) { return v1 * v2 * v3; }
Int mult(Int v1, Int v2, Int v3)

어떤 함수가 자동으로 제네릭 함수가 되었다는 걸 개발자가 몰랐다면 문제가 생긴다.
왜냐하면 타입 검사기가 알려주는 오류 메시지를 이해하기 어려워지기 때문이다.
그래서 이런 오류를 접하면 함수에 매개변수 타입 표시를 추가해서 확인해 보는게 좋다.

3.2 제네릭 타입

어떤 타입 A가 있을 때 A의 리스트를 타입으로 표현하고 싶다면
매개변수에 의한 다형성을 통해 어떤 타입의 리스트인지 결정하게 하면 제네릭 타입이라고 얘기할 수 있다.

제네릭 클래스

개발자가 자신만의 제네릭 타입을 직접 정의해 클래스를 만들 수 있다면 제네릭 클래스라고 한다.
타입 매개변수를 가지는 클래스이고 정의할 때는 제네릭 함수와 비슷하게 사용한다.

3.3 무엇이든 타입

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2025 타입으로 견고하게 다형성으로 유연하게 탄탄한 개발을 위한 씨줄과 날줄
Projects
Status: In progress
Development

No branches or pull requests

1 participant