- [Expression Problem] 표현 문제란?
- [Expression Problem] Open classes , Protocol , 그리고 확장 메서드
- [Expression Problem] Type classes -> 지금 여기
- [Expression Problem] Mutiple Dispatch (Feat Visitor / Multi Method)
- [Expression Problem] 객체 대수 (Object algebras) 와 Tagless Final
type class 는 Haskell (및 Scala + implicit .. , Rust) 에서 주로 사용하는 기능으로
adhoc (임시적) 다형성을 제공하는 기술이다. (Haskell 을 해본적이 없어서 설명이나 예시가 정확하지는 않음..)
type class 를 상속받으면 해당 기능을 구현해야 하고, 해당 type class 에 대한 다형성을 가짐
엥 이거 완전 interface 아니냐?
Interface 를 상속 받으면 해당 기능을 구현해야 하고, 해당 interface 에 대한 다형성을 가짐
그럼 인터페이스와 차이가 뭘까?
interface 는 해당 interface 를 상속 받기위해서는 class가 선언됨과 동시에 어떤 다형성을 가질지 Interface 를 명시해야한다
즉
interface Character {
fun hit()
fun skill()
}
interface Monster {
fun bark()
}
class Tanker : Character, Monster {
val hp: Int = 100
override fun hit() { println("Tanker Hit") }
override fun skill() { println("Tanker Skill") }
override fun bark() { println("Tanker Skill") }
}
이 코드는 가능해도
interface Character {
fun hit()
fun skill()
}
interface Monster {
fun bark()
}
class Tanker : Character{
val hp: Int = 100
override fun hit() { println("Tanker Hit") }
override fun skill() { println("Tanker Skill") }
}
// 오랜시간이 지난후..
class Tanker : Monster {
override fun bark() { println("Monster bark") }
}
이건 안된다는 말이다.
그러나 Type class 는 다르다, Type class는 인스턴스화 할때, 그 대상이 Implicit(암시적)으로 타입클래스의 기능을 가지게 된다.
-- 기존의 FP 식 정의 -> 기본적으로 Close 한 타입이므로 해당 타입에 대해여 확장은 X
-- data Character = Healer Int | Knight Int
-- 확장을 위해서는 type class 사용 -> 기본적으로 각 데이터는 무관함
data Healer = Healer Int
data Knight = Knight Int
-- 각 type 을 Type Class 로 정의?함
class Character c
instance Character Healer
instance Character Knight
즉 Implicit (암시적으로) 적용되는 Adhoc(임시적) 인터페이스 같은 녀석이다.
-- Monster는 bark 함수를 가지는 Type class, Character Type class 로 부터 drived 됨
class (Character c) => Monster c where
bark :: c -> String
-- Healer 는 이제 Monster type class 의 함수가 정의될 수 있음
instance Monster Healer where
bark (Healer x) = blahblah
Healer 는 이제(Adhoc) skill/hit/bark 를 모두 가진다. (FP 처럼 함수를 확장)
-- 새 Type 이 정의되는것도 가능 (like Interface)
data Tanker = blah blah
instance Character Tanker
Tanker 는 Character 를 구현한 data 이다. (인터페이스처럼 서브타입 확장)
type class 를 사용하면 두개 모두 가능하다. 와~~
하지만 type class의 문제점은, type class는 type class 이지 type 이 아니라는 점이다 (??)
let x = 20
let who = if x > 4 then (Healer 100) else (Knight 100) #-> Error!!
who의 Type 은 Healer 가 될수도, Knight 가 될수도 있다. (x 값에 따라)
haskell 은 강력한 정적 타입언어이므로, who 의 타입이 (컴파일 타임에) 명확하게 추론되어야 하는데, 우리는 Healer 와 Knight 를 adhoc(임시적) 으로 묶어놓은것이므로, 위와 같은 코드가 불가능하다.
그래서... type 을 만들고 type 컨스트럭터를 이용해서 두개를 아주 복잡하게 적절하게 사용해서 문제를 해결할수있지만, 일단 어렵고, 포스팅의 범위를 넘어가는것 같아서 생략.. [자세한 설명] 참조
'프로그래밍 기술 노트 > Functional Study' 카테고리의 다른 글
[Expression Problem] 객체 대수 (Object algebras) 와 Tagless Final (0) | 2022.04.28 |
---|---|
[Expression Problem] Mutiple Dispatch (Feat Visitor / Multi Method) (0) | 2022.04.27 |
[Expression Problem] Open classes , Protocol , 그리고 확장 메서드 (0) | 2022.04.26 |
[Expression Problem] 표현 문제란? (0) | 2022.04.26 |
[Optics/Lens] 내 멋대로 Optics 이해하기 Feat) arrow-kt (2) | 2022.04.20 |