【发布时间】:2014-10-25 05:43:14
【问题描述】:
Learn You a Haskell 呈现 Prob 新类型:
newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show
这是Prob 的定义:
instance Functor Prob where
fmap f (Prob xs) = Prob $ map (\(x,p) -> (f x,p)) xs
instance Monad Prob where
return x = Prob [(x, 1%1)]
p >>= f = flatten (fmap f p)
然后是辅助功能:
flatten :: Prob (Prob a) -> Prob a
flatten = Prob . convert . getProb
convert :: [(Prob a, Rational)] -> [(a, Rational)]
convert = concat . (map f)
f :: (Prob a, Rational) -> [(a, Rational)]
f (p, r) = map (mult r) (getProb p)
mult :: Rational -> (a, Rational) -> (a, Rational)
mult r (x, y) = (x, r*y)
我编写了 flatten、convert、f 和 mult 函数,所以我对它们很满意。
那么我们将>>=应用到下面的例子中,涉及到一个数据类型Coin:
data Coin = Heads | Tails deriving (Show, Eq)
coin :: Prob Coin
coin = Prob [(Heads, 1%2), (Tails, 1%2)]
loadedCoin :: Prob Coin
loadedCoin = Prob [(Heads, 1%10), (Tails, 9%10)]
LYAH 说,If we throw all the coins at once, what are the odds of all of them landing tails?
flipTwo:: Prob Bool
flipTwo= do
a <- coin -- a has type `Coin`
b <- loadedCoin -- similarly
return (all (== Tails) [a,b])
调用flipTwo 返回:
Prob {getProb = [(False,1 % 20),(False,9 % 20),(False,1 % 20),(True,9 % 20)]}
flipTwo可以用>>=重写:
flipTwoBind' :: Prob Bool
flipTwoBind' = coin >>=
\x -> loadedCoin >>=
\y -> return (all (== Tails) [x,y])
我不了解return (all (== Tails) [x,y]) 的类型。由于它是>>= 的右侧,那么它的类型必须是a -> m b(其中Monad m)。
我的理解是(all (==Tails) [x,y])返回True or False,但是return是如何导致上述结果的:
Prob {getProb = [(False,1 % 20),(False,9 % 20),(False,1 % 20),(True,9 % 20)]}?
【问题讨论】:
标签: haskell