В книге «Изучайте Haskell во имя добра» есть такой пример:
import Data.Ratio
import Data.List (all)
newtype Prob a = Prob { getProb :: [(a, Rational)] } deriving Show
instance Functor Prob where
fmap f (Prob xs) = Prob $ map (\(x, p) -> (f x, p)) xs
flatten :: Prob (Prob a) -> Prob a
flatten (Prob xs) = Prob $ concat $ map multAll xs
where multAll (Prob innerxs, p) = map (\(x, r) -> (x, p * r)) innerxs
instance Monad Prob where
return x = Prob [(x, 1 % 1)]
m >>= f = flatten (fmap f m)
data Coin = Heads | Tails deriving (Show, Eq)
coin :: Prob Coin
coin = Prob [(Heads, 1 % 2), (Tails, 1 % 2)]
loadCoin :: Prob Coin
loadCoin = Prob [(Heads, 1 % 10), (Tails, 9 % 10)]
flipThree :: Prob Bool
flipThree = do
a <- coin
b <- coin
c <- loadCoin
return (all (==Tails) [a, b, c])
flipThree' :: Prob [Coin]
flipThree' =
coin >>= (\x ->
coin >>= (\y ->
loadCoin >>= (\z ->
return [x, y, z])))
Результат flipThree'
Prob {getProb = [([Heads,Heads,Heads],1 % 40),([Heads,Heads,Tails],9 % 40),([Heads,Tails,Heads],1 % 40),([Heads,Tails,Tails],9 % 40),([Tails,Heads,Heads],1 % 40),([Tails,Heads,Tails],9 % 40),([Tails,Tails,Heads],1 % 40),([Tails,Tails,Tails],9 % 40)]}
Prob [([([Heads,Heads,Heads],GHC.Real.:% 1 20),
([Heads,Heads,Tails],GHC.Real.:% 9 20),
([Heads,Tails,Heads],GHC.Real.:% 1 20),
([Heads,Tails,Tails],GHC.Real.:% 9 20)],GHC.Real.:% 1 2),
([([Tails,Heads,Heads],GHC.Real.:% 1 20),
([Tails,Heads,Tails],GHC.Real.:% 9 20),
([Tails,Tails,Heads],GHC.Real.:% 1 20),
([Tails,Tails,Tails],GHC.Real.:% 9 20)],GHC.Real.:% 1 2)]
Prob [([([Heads,Heads],GHC.Real.:% 1 10),
([Heads,Tails],GHC.Real.:% 9 10)],GHC.Real.:% 1 2),
([([Tails,Heads],GHC.Real.:% 1 10),
([Tails,Tails],GHC.Real.:% 9 10)],GHC.Real.:% 1 2),
([([Heads,Heads],GHC.Real.:% 1 10),
([Heads,Tails],GHC.Real.:% 9 10)],GHC.Real.:% 1 2),
([([Tails,Heads],GHC.Real.:% 1 10),
([Tails,Tails],GHC.Real.:% 9 10)],GHC.Real.:% 1 2)]
fmap f m
f