計算機科学のブログ

型によるプログラミング 合成によるデザイン SemigroupとMonoid 単位元による合成、mempty関数、mappend関数、mconcat関数

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

コード

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

instance Semigroup Color where
  (<>) Transparent c = c
  (<>) c Transparent = c
  (<>) 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 = Transparent
    mappend c1 c2 = c1 <> c2

入出力結果(Terminal, Zsh)

% ghci
GHCi, version 8.10.5: https://www.haskell.org/ghc/  :? for help
macro 'doc' overwrites builtin command.  Use ':def!' to overwrite.
(0.00 secs, 0 bytes)
(0.00 secs, 0 bytes)
Loaded GHCi configuration from /.../.ghc/ghci.conf
Prelude
λ> :load sample1
[1 of 1] Compiling Main             ( sample1.hs, interpreted )
Ok, one module loaded.
(0.13 secs,)
*Main
λ> mconcat [Red]
Red
it :: Color
(0.01 secs, 64,560 bytes)
*Main
λ> mconcat []
()
it :: Monoid a => a
(0.01 secs, 60,504 bytes)
*Main
λ> mempty
()
it :: Monoid a => a
(0.01 secs, 60,296 bytes)
*Main
λ> mconcat [] :: Color
Transparent
it :: Color
(0.01 secs, 68,096 bytes)
*Main
λ> mempty :: Color
Transparent
it :: Color
(0.00 secs, 68,048 bytes)
*Main
λ> mconcat [Red, Blue, Red]
Purple
it :: Color
(0.01 secs, 64,856 bytes)
*Main
λ> mconcat [Red, Blue, Purple]
Purple
it :: Color
(0.01 secs, 65,272 bytes)
*Main
λ> mconcat [Red, Blue, Orange]
Brown
it :: Color
(0.00 secs, 66,080 bytes)
*Main
λ> :quit
Leaving GHCi.
%