이 글은 Learn You a Haskell for Great Good 중 일부를 정리한 것이다.
타입 Ordering은 뭔가 비교한 결과를 표현할 때 쓴다. Ordering에는 값이 세 개 있다.
data Ordering =
LT
| EQ
| GTLT: Less ThanEQ: EqualGT: Greater Than
아래와 같이 함수 compare로 두 수를 비교하면 결과로 타입 Ordering의 값 중 하나가 나온다.
ghci> 1 `compare` 2
LT
ghci> 2 `compare` 2
EQ
ghci> 3 `compare` 2
GT세미그룹과 모노이드 인스턴스는 아래와 같다.
instance Semigroup Ordering where
LT <> _ = LT
EQ <> y = y
GT <> _ = GT
instance Monoid Ordering where
mempty = EQ
mappend = (<>)- 항등원은
EQ이다. <>에 먼저 들어온 것이EQ일 경우 나중에 들어온 것이 결과가 된다.- 그렇지 않을 때는 그냥 먼저 들어온 것이 결과가 된다.
두 문자열의 길이를 비교해서 결과로 타입 Ordering이 나오는 함수를 만들어 보자. 그런데 만약 길이가 같으면 알파벳 순으로 크기를 결정한다.
lengthCompare :: String -> String -> Ordering
lengthCompare x y =
let a = length x `compare` length y
b = x `compare` y
in if a == EQ then b else aa는 길이를 비교한 결과b는 알파벳순으로 비교한 결과- 길이가 같으면
b가 결과가 되고 그렇지 않으면a가 결과가 된다.
Ordering도 모노이드라는 점을 이용하면 아래와 같이 더 쉽게 할 수 있다.
lengthCompare x y =
(length x `compare` length y)
<> (x `compare` y)ghci> lengthCompare "zen" "ants"
LT
ghci> lengthCompare "zen" "ant"
GT
Ordering 모노이드는 먼저 오는 것이 EQ가 아니라면 먼저 온 것이 결과가 된다. 따라서 위와 같이 여러 조건을 우선 순위에 따라 비교하고 싶을 때 더 중요하다고 생각하는 조건을 맨 앞에 두면 된다.
위 예제에서 검사 조건을 하나 더 추가해보자. 이번에는 문자열 중 모음의 개수를 두 번째 조건으로 추가한다.
lengthCompare x y =
(length x `compare` length y)
<> (vowels x `compare` vowels y)
<> (x `compare` y)
where vowels = length . filter (`elem` "aeiou")함수 vowels는 문자열을 입력하면
- 문자열에서
"aeiou"에 속하는 글자만filter로 골라내고 - 그 길이가 결과로 나온다.
ghci> lengthComapre "zen" "anna"
LT
ghci> lengthComapre "zen" "ana"
LT
ghci> lengthCompare "zen" "ann"
GT