型によるプログラミング 合成によるデザイン:SemigroupとMonoid 確率テーブルの構築
入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT3(型によるプログラミング)、LESSON17(合成によるデザイン:SemigroupとMonoid)、17.5(練習問題)Q17-2の解答を求めてみる。
コード
data Events = Events [String] deriving (Show)
data Probs = Probs [Double] deriving (Show)
cartCombine :: (a -> b -> c) -> [a] -> [b] -> [c]
cartCombine func l1 l2 =
let nToAdd = length l2
repeatedL1 = map (take nToAdd . repeat) l1
newL1 = mconcat repeatedL1
cycledL2 = cycle l2
in zipWith func newL1 cycledL2
instance Semigroup Events where
(<>) (Events e1) (Events e2) =
let combiner = \x y -> mconcat [x, "-", y]
in Events $ cartCombine combiner e1 e2
instance Semigroup Probs where
(<>) (Probs p1) (Probs p2) = Probs $ cartCombine (*) p1 p2
coinEvents :: Events
coinEvents = Events ["heads", "tails"]
coinProbs :: Probs
coinProbs = Probs [0.5, 0.5]
spinnerEvents :: Events
spinnerEvents = Events ["red", "blue", "green"]
spinnerProbs :: Probs
spinnerProbs = Probs [0.1, 0.2, 0.7]
main = do
print $ (<>) coinEvents spinnerEvents
print $ (<>) coinProbs spinnerProbs
入出力結果(Terminal, Zsh)
% runghc sample2.hs
Events ["heads-red","heads-blue","heads-green","tails-red","tails-blue","tails-green"]
Probs [5.0e-2,0.1,0.35,5.0e-2,0.1,0.35]
%