대수적 데이터 타입(ADT)은 정해진 개수의 이름 붙은 케이스를 나타내요. ADT의 각 값은 그중 정확히 하나의 케이스에 해당해요.
ADT는 data 키워드로 정의하고, 케이스는 파이프(|) 문자로 구분해요.
케이스에 연결된 데이터가 하나도 없으면, 그 ADT는 다른 언어에서 흔히 열거형(enum)이라고 부르는 것과 비슷해요.
data Season
= Spring
| Summer
| Autumn
| Winter
ADT의 각 케이스에는 데이터를 선택적으로 연결할 수 있고, 케이스마다 다른 타입의 데이터를 가질 수 있어요. 케이스에 데이터가 연결되어 있으면 생성자가 필요해요.
data Number
= NInt Int --'NInt' is the constructor for an Int Number.
| NFloat Float --'NFloat' is the constructor for an Float Number.
| Invalid --'Invalid' does not have data associated to it.
특정 케이스의 값을 만들려면 그 케이스의 이름을 쓰면 돼요(예: NInt 22).
케이스 이름은 그냥 생성자 함수이기 때문에, 연결할 데이터는 일반 함수의 인자처럼 넘길 수 있어요.
ADT는 _구조적 동등성_을 가져요. 즉, 같은 케이스에 속하고 (있다면) 데이터도 같은 두 값은 서로 같아요.
ADT를 다룰 때 if/else 표현식을 쓸 수도 있지만, 권장하는 방법은 case 문을 사용한 패턴 매칭이에요.
add1 :: Number -> String
add1 number =
case number of
NInt i -> show (i + 1)
NFloat f -> show (f + 1.0)
Invalid -> error "Invalid input"
이 연습 문제에서는 밸런타인데이를 맞아 파트너와 무엇을 할지 계획하고 있어요. 파트너는 아이디어가 아주 많아서, 가장 좋은 활동을 찾기 위해 아이디어를 평가해 달라고 해요.
파트너가 제안한 아이디어는 다음과 같아요:
밸런타인데이 활동을 고르는 데 도움이 될 여섯 가지 과제가 있어요.
파트너가 제안한 각 아이디어에 대해 예, 아니요, 어쩌면 중 하나로 답해요.
다음 세 가지 경우를 나타내는 Approval 대수적 데이터 타입을 정의해요: Yes, No, Maybe.
파트너는 두 곳의 식당을 골랐어요: 하나는 한국 요리, 다른 하나는 터키 요리예요.
Cuisine 대수적 데이터 타입을 정의해서 이 식당들을 다음 두 가지 경우로 나타내요: Korean 또는 Turkish.
고를 수 있는 영화가 정말 많아서, 선택의 폭을 좁히기 위해 파트너는 선호하는 장르도 알려줘요.
Genre 대수적 데이터 타입을 정의해서 다음 장르 경우들을 나타내요: Crime, Horror, Romance 또는 Thriller.
앞서 말했듯이, 파트너는 다섯 가지 가능한 활동을 생각해 냈어요: 보드 게임 하기, 쉬기, 영화 보기, 식당 가기, 산책하기.
Activity 대수적 데이터 타입을 정의해서 다음 활동 타입들을 나타내요:
BoardGame: 연관된 데이터가 없어요.Chill: 연관된 데이터가 없어요.Movie: Genre를 연관 데이터로 가져요.Restaurant: Cuisine을 연관 데이터로 가져요.Walk: 걷는 거리(킬로미터)를 나타내는 Int를 연관 데이터로 가져요.이제 파트너의 아이디어를 평가할 준비가 됐어요. 파트너의 아이디어에 대한 생각은 이래요:
Activity 값을 받아 위에서 정한 느낌에 따라 Approval을 반환하는 rateActivity라는 함수를 구현해요.
예를 들어:
rateActivity (Restaurant Turkish)
-- -> Maybe
Exercism에 가입하고 Haskell 트랙을 연습 문제 107개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.