Elm에서는 동등 연산자 (==)로 타입이 "같은지" 확인할 수 있어요.
부등 연산자는 (/=)예요 (많은 언어의 !=가 아니에요).
동등 연산자는 리터럴, 튜플, 레코드, 커스텀 타입에 사용할 수 있어요.
1 == 2
--> False
1 /= 2
--> True
(1, 2) == (2, 1)
--> False
type alias MyRecord = { myInt : Int, myStrings : List String }
a : MyRecord
a = MyRecord (1 + 1) ["hello world"]
type alias MyOtherRecord = { myInt : Int, myStrings : List String }
myStrings = (String.join " " ["hello", "world"]) :: []
b : MyOtherRecord
b = { myInt = 2, myStrings = myStrings}
a == b
--> True
함수는 절대 비교하면 안 돼요. 런타임에 프로그램이 크래시 나거든요.
비교 연산자 (<), (<=), (>), (>=)와 함수 min, max, compare는 comparable 타입에서 동작해요.
comparable 타입은 비교할 수 있는 모든 내장 타입을 묶은 특별한 타입이에요. 숫자, 문자, 문자열, comparable한 것들의 리스트, comparable한 것들의 튜플이 여기에 속해요.
1 < 1 + 1
--> True
'x' < 'X'
--> False
"abc" < "abz"
--> True
"abc" < "abcd"
--> True
"abc" < "b"
--> True
min [1 , 2, 9000] [10]
--> [1 , 2, 9000]
min (1, "hello") (3, "bye")
--> (1, "hello")
레코드나 커스텀 타입처럼 다른 타입의 값은 직접 비교할 수 없어요.
Set이나 Dict의 키처럼 일부 내장 타입은 내부 정렬에 의존하기 때문에 내용이 comparable해야 해요.
comparable 값들의 리스트는 List.sort로 정렬할 수 있고, comparable 값으로 매핑할 수 있는 값들의 리스트는 List.sortBy로 정렬할 수 있어요.
여러 단계로 정렬해야 한다면 (한 속성으로 정렬하고, 값이 같으면 다른 속성으로 순서를 정한다면) 튜플이나 리스트도 List.sortBy와 함께 사용할 수 있어요. 튜플과 리스트는 사전순으로 정렬되기 때문이에요.
List.sort ["hi", "hello", "bye", "goodbye"]
--> ["bye", "goodbye", "hello", "hi"]
List.sortBy String.length ["hi", "hello", "bye", "goodbye"]
--> ["hi", "bye", "hello", "goodbye"]
-- sort by length, then alphabetically
List.sortBy (\str -> (String.length str, str)) ["hi", "mum", "hello", "sis", "bye", "dad"]
--> ["hi", "bye", "dad", "mum", "sis", "hello"]
compare 함수는 comparable 값 두 개를 받아서 Order를 반환해요.
Order는 어떤 값이 다른 값보다 큰지(GT), 같은지(EQ), 작은지(LT)를 한 번의 연산으로 확인하는 타입이에요.
compare 1 2
--> LT
compare "" ""
--> EQ
compare [12] []
--> GT
비교 함수는 임의의 타입에 대해 만들 수 있고, 예를 들어 List.sortWith로 정렬하는 데 사용할 수 있어요:
type Color = Red | Green | Blue
compareColors : Color -> Color -> Order
compareColors a b =
case (a, b) of
(Red, Red) -> EQ
(Red, _) -> LT
(_, Red) -> GT
(Green, Green) -> EQ
(Green, _) -> LT
(_, Green) -> GT
(Blue, Blue) -> EQ
List.sortWith compareColors [Blue, Red, Green, Green, Blue]
--> [Red, Green, Green, Blue, Blue]
문득 향수가 밀려오고, 오래된 Blorkemon™️ 카드의 먼지를 털어내고 싶은 강한 충동이 생겨요.
Blorkemon™️ 카드는 훌륭한 옛날식 카드 교환 게임이에요.
각 Card에는 Blorkemon™️ 몬스터가 그려져 있고, 공격력 레벨도 함께 있어요. 운이 좋으면 카드가 shiny일 수도 있어요.
Blorkemon™️ 카드는 하나같이 다음 카드보다 더 강해 보이지만, 직접 확인해 보는 게 좋아요.
isMorePowerful 함수를 구현해요. 첫 번째 인자로 받은 카드가 다른 카드보다 엄격하게 더 강하면 True를, 그렇지 않으면 False를 반환해야 해요.
newthree = Card "Newthree" 120 False
scientuna = Card "Scientuna" 6 True
isMorePowerful newthree scientuna
--> True
손에 Blorkemon™️ 카드가 가득 있으면, 가장 강력한 공격을 준비할 수 있어야 해요.
maxPower 함수를 구현해요. 이 함수는 카드 두 장 중 가장 높은 공격력을 반환해요.
maxPower newthree scientuna
--> 120
모든 Blorkemon™️ 카드를 적어도 한 장씩은 가지고 있었던 것 같은데, 마지막으로 확인한 지도 꽤 오래됐어요. Pulpapedia의 공식 목록과 비교하려면 카드를 정렬하는 게 좋겠어요.
sortByMonsterName 함수를 구현해요. 이 함수는 Cards 목록을 받아 몬스터 이름순으로 정렬한 목록을 반환해야 해요.
sortByMonsterName [newthree, scientuna]
--> [Card "Newthree" 120 False, Card "Scientuna" 6 True]
Blorkemon™️은 세상에서 가장 멋진 존재예요. 그냥 가볍게 하는 말이 아니라, 이를 증명할 과학적인 방법도 있어요.
sortByCoolness 함수를 구현해요. 이 함수는 가장 멋진 카드를 앞에 두는 순서로 카드 목록을 정렬해요.
카드의 멋짐은 먼저 shiny 여부로 결정돼요. shiny 카드는 모두 다른 카드보다 훨씬 멋져요.
두 번째 기준은 공격력으로, 높을수록 좋아요.
sortByCoolness [newthree, scientuna]
--> [Card "Scientuna" 6 True, Card "Newthree" 120 False]
shiny는 겉치레만이 아니에요. 공격력이 비슷한 Blorkemon™️끼리 싸우면, shiny 쪽이 항상 이겨요. 이것을 Shiny Power라고 불러요.
compareShinyPower 함수를 구현해요. 이 함수는 이 속성을 규칙으로 담아내요.
두 카드의 공격력이 다르면 그 값으로 Order가 정해지고, 같으면 shiny 카드가 더 커요.
compareShinyPower newthree scientuna
--> GT
Blorkemon™️ 카드 게임에서는 무슨 일이든 일어날 수 있지만, 그래도 더 강한 카드가 이기는 경향이 있어요.
expectedWinner 함수를 구현해요. 이 함수는 compareShinyPower 순서를 기준으로, 이길 가능성이 가장 높은 몬스터의 이름을 반환해요.
예상 승자의 몬스터 이름을 반환하고, 두 상대의 Shiny Power가 같으면 "too close to call"을 반환해야 해요.
expectedWinner newthree scientuna
--> "Newthree"
Exercism에 가입하고 Elm 트랙을 개념 28개연습 문제 110개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.