6.6.5. Generalised derived instance for newtypes
재미난게, 영어 스펠링이 나라에 따라 s
나 z
가 쓰이고 있어, Generalised(영국), Generalized 둘 다 준비 해놨습니다.
newtype Dollars = Dollars Int
이 확장이 없이 Dollars
를 더하기 하려면, 명시적으로 Dollars
를 Num
클래스의 인스턴스로 정의해야 합니다.
instance Num Dollars where
Dollars a + Dollars b = Dollars (a + b)
^^^^^^^ ^^^^^^^ ^^^^^^^
위 인스턴스 정의가 하는 일은 Dollars
생성자를 적용하는 일만 하고 있습니다. 생성자는 런타임에선 사라지기 때문에, 이 인스턴스 선언은 Int
딕셔너리1와 완전히 동일한 정의입니다.
※ 이 아이디어를 일반화한 게 확장 DerivingVia 입니다.
GeneralisedNewtypeDeriving
확장을 켜면, 다음처럼만 쓰면 GHC가 인스턴스를 유도해 줍니다.
newtype Dollars = Dollars { getDollars :: Int } deriving (Eq, Show, Num)
구현은 Int
의 Num
딕셔너리를 씁니다. 다시 말해, GHC가 다음과 비슷한 걸 생성합니다.
instance Num Int => Num Dollars
※ 위 표현이 낯섭니다. Num Int
란 제약이 있는데 =>
오른 쪽에 Int
가 없습니다. Dollars
가 안에 Int
를 가지고 있긴 한데, 이런 식으로 써도 되는지 아직 “문법” 자체를 잘 모르겠습니다.
GHC는 Num Int
인스턴스가 유효 스코프에 있는 걸 알기 때문에, 다음 처럼만 생성합니다.
instance Num Dollars
…작성 중
타입이 갖고 있는 인스턴스 목록을 타입 클래스 딕셔너리, 혹은 그냥 딕셔너리라고 하는 것 같습니다.↩︎