본 글은 프로그래밍 언어론과 하스켈 언어에 대해 학습하는 글입니다.
이번엔 하스켈의 유형중 타입과 타입클래스, 인스턴스에 대해 설명해봅니다.
타입은 기본적으로 하스켈 라이브러리에서 지원되는 built in 타입이 있다.
하지만 개발자의 임의대로 사용자정의 타입을 생성할수 있는데 이 방법에 대해서는 이전 문서를 통해 설명하였다.
타입은 data 키워드를 통해 정의되는데 먼저 다음 예시를 보자.
data Numbers = None | One Int | Two Int Int
이 코드를 보면 Numbers 라는 기존에 존재하지 않던 타입을 새롭게 정의한것으로,
이때 None, One, Two 은 사용자가 정의한 데이터 생성자이다.
그런데 이렇게 타입 Numbers 를 정의해두면 자유롭게 해당 타입을 쓸수 있을까?
그리고 타입을 정의하면 뭘 어떻게 사용하는걸까?
타입의 존재 이유에 대해 다시한번 짚어보면,
타입은 하스켈에서 함수 다음으로 중요하고 매우매우 static한 영역이다.
이는 소스코드에서 AST로의 변환과정에서 예기치 못한 에러발생을 줄인다.
때문에 타입에 대한 매칭은 엄격해야하는데, 일반적으로 함수의 동작에서 타입매칭이 필수적이다.
함수를 사용하기 위해서는 먼저 함수의 입출력 타입의 정의가 우선되어야하고, 그다음으로 함수의 연산을 구현해야한다.
이때 함수 입출력 타입 정의부분을 타입 클래스에 진행한다.
타입 클래스는 타입의 집합으로 오해하기 쉽지만 정확하게는 함수 입출력 타입 정의의 집합이다.
이때 함수들이 동작할때, 개입되는 타입들이 함수 정의에 녹아서 타입클래스에 기록되는 방식이다.
그렇다면 새로운 타입에 대한 정의도 완료되었고, 함수 입출력 타입에 대한 정의도 타입클래스에 기록하였다.
마지막으로 남은것은 함수 자체의 구현이다.
함수의 구현은 어디서 어떻게 이루어지는가?
함수의 실제 연산은 함수가 어떤 타입을 인자로 받아서 동작하는지에 따라 다르다( Polymorphism )
함수는 고정된 타입의 인자를 전달받을수도 있지만, 전달받는 타입에 따라 다르게 동작할것을 요구받을수 있다.
앞서 타입 클래스는 함수 입출력 과정에서 데이터들의 타입을 정의해둔 곳이라 설명했다.
타입 클래스에 정의해둔 타입은 static(정의된 타입)이거나 a(정의되지 않은 타입 == 어떤 타입이든 처리함)인 경우로 나뉜다.
일반적으로 다양한 인자를 받아 처리하는 함수는 Polymorphism 요구되므로 각각의 인자 타입마다 서로 다른 기능을 구현할 필요가 있다.
그런데 타입 클래스 하나에서 하나의 함수가 전달 인자마다 다르게 동작하는것을 정의하기엔 가독성이 떨어진다.
그래서 타입클래스에 함수의 동작을 구현하지 않고 별도의 인스턴스를 만든다.
인스턴스는 타입클래스에 정의된 함수와 입출력 타입을 그대로 상속 받아서 사용자 정의 타입별로 서로 독립적인 공간을 만든다.
이로인해 하나의 함수가 전달인자의 타입마다 별도의 독립된 공간에서 다른 기능을 수행할수 있게 된다.
다음은 조악하게나마 그려봄.. 함수와 인자와 타입과 타입클래스와 인스턴스가 왜 필요하고 어떻게 동작하는가? 에 대한 정리.
'프로그래밍언어 > Haskell' 카테고리의 다른 글
[Haskell] 프로그래밍 언어론 - 하스켈 언어(3) - Types (0) | 2025.03.24 |
---|---|
[Haskell]프로그래밍 언어론 - 하스켈 언어(2) - GHCI 와 Stack (0) | 2025.03.16 |
[Haskell]프로그래밍 언어론 - 하스켈 언어(1) - Compile, translate (0) | 2025.03.16 |