请帮我理解下面的haskell代码.
data Coin = Heads | Tails deriving ({-hi-}Eq, {-/hi-} Show,Enum,Bounded)
instance Random Coin where
randomR (a,b) g =
case randomR (fromEnum a, fromEnum b) g of
(x,g') -> (toEnum x,g')
random g = randomR (minBound,maxBound) g
coins = do
g <- newStdGen
print . take 10 $ (randoms g::[Coin])
count = 10000
process :: [Coin] -> (Int,Int)
process cs = (length cs,length (filter (== Heads) cs))
display::(Int,Int) -> String
display (coins,heads) = "We got " ++ (show $ 100.0 * fromIntegral heads / fromIntegral coins) ++ "% heads. "
r = do
g <- newStdGen
putStrLn . display .process . take count $ randoms g
Run Code Online (Sandbox Code Playgroud)
我无法得到什么{-hi-}Eq, {-/hi-} Show意思.
以下,"of"和下一部分的意义是什么.
case randomR(fromEnum a,fromEnum b)g of(x,g') - >(toEnum x,g')
Coin是具有两个构造代数数据类型,Heads并且Tails,表示与两个值的枚举.它与(具有相同的结构)同构,Bool但是是不同的类型.
deriving (Eq, Show, Enum, Bounded) 自动生成类型类的实现:
Eq,支持测试相等性的类型 ==
Show,用于将值转换为字符串以进行调试
Enum,用于使用前驱函数pred和后继函数枚举值succ
Bounded,有minBound(这里Heads)和maxBound(Tails)的类型
{-... -}只是一个注释,编译器会忽略它; 看来作者打算使用某种不能正常工作的非Haskell格式表示法.
instance Random Coin where开始实现Random类型的Coin类型类,实现随机生成硬币.它有两种方法的实现:
randomR (a, b) g描述了如何生成的范围内的随机值a来b使用随机发生器g.实现调用在参数范围内randomR生成随机整数a并b使用Enum该类.如果a是Heads则fromEnum a是0; 如果b是Tails则fromEnum b是1.所述case... of符号执行模式匹配对这个函数的结果,得到一个对一个随机值的x和更新的随机发生器g'(发音为"G素").然后它x从一个整数转换回一个Coinusing toEnum,并返回硬币值和更新的生成器.
random描述了如何仅从生成器生成随机硬币,而不将范围作为输入.它使用给定的生成器在minBound(Heads)和maxBound(Tails)之间产生抛硬币g.
coins是一个IO动作,创建一个新的标准随机生成器newStdGen,然后从该生成器生成随机硬币投掷的无限列表(流)randoms g :: [Coin].它用于take获取该列表的前10个元素并输出它们print.
r类似于coins,但也运行掷硬币通过process函数,它返回一对它被赋予(硬币数的length cs)和那些的数量Heads(length (filter (== Heads) cs)); 以及将display结果格式化为字符串百分比的函数.