計算機科学のブログ

Haskell - 型によるプログラミング - 合成によるデザイン:SemigroupとMonoid - 色、単位元、インスタンス

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)の UNIT3(型によるプログラミング)、LESSON 17(合成によるデザイン:SemigroupとMonoid)、17.5(練習問題)、Q17-1の解答を求めてみる。

コード

sample.hs

main :: IO ()
main = do
    print $ Clear <> Red
    print $ Red <> Clear
    print $ (Red <> Yellow) <> Blue
    print $ Red <> (Yellow <> Blue)
    print $ mconcat [Green ,Purple , Orange]

data Color = Clear | Red | Yellow | Blue | Green | Purple | Orange | Brown 
    deriving (Show, Eq)

instance Semigroup Color where
    (<>) :: Color -> Color -> Color
    (<>) Clear color = color
    (<>) color Clear = color
    (<>) Red Blue = Purple
    (<>) Blue Red = Purple
    (<>) Yellow Blue = Green
    (<>) Blue Yellow = Green
    (<>) Yellow Red = Orange
    (<>) Red Yellow = Orange
    (<>) a b | a == b = a
             | all (`elem` [Red, Blue, Purple]) [a, b] = Purple
             | all (`elem` [Blue, Yellow, Green]) [a, b] = Green
             | all (`elem` [Red, Yellow , Orange]) [a, b] = Orange
             | otherwise = Brown

instance Monoid Color where
    mempty :: Color
    mempty = Clear
    mappend :: Color -> Color -> Color
    mappend = (<>)

入出力結果(Terminal, Zsh)

% runghc sample.hs
Red
Red
Brown
Brown
Brown
%