首页 > 解决方案 > 了解haskell随机硬币生成代码

问题描述

请帮助我理解下面的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
  1. 我不明白 是{-hi-}Eq, {-/hi-} Show什么意思。

  2. 以及下面,“of”和下一部分的意义是什么。

case randomR (fromEnum a, fromEnum b) g of (x,g') -> (toEnum x,g')

标签: haskell

解决方案


Coin是具有两个构造函数的代数数据类型,Heads并且Tails表示具有两个值的枚举。它与(具有相同的结构)同构,Bool但是是一种不同的类型。

deriving (Eq, Show, Enum, Bounded)自动生成类型类的实现:

  • Eq, 支持测试相等性的类型类==

  • Show, 用于将值转换为字符串以进行调试

  • Enum,用于枚举具有前任和后继功能的值,pred以及succ

  • Bounded, 具有minBound(here Heads) 和maxBound( Tails)的类型

  • {-…<code>-} 只是一个注释,编译器会忽略它;看来作者打算使用某种无法正常工作的非 Haskell 格式符号。

instance Random Coin where开始实现该Random类型的Coin类型类,从而实现硬币的随机生成。它有两种方法的实现:

  • randomR (a, b) g描述了如何在使用随机生成器的范围a内生成随机值。实现调用以生成参数范围内的随机整数并使用类。如果是那么是; 如果是那么是。...<code> 表示法对该函数的结果执行模式匹配,得到一对随机值和一个更新的随机生成器(发音为“G prime”)。然后它从一个整数转换回一个使用bgrandomRabEnumaHeadsfromEnum a0bTailsfromEnum b1casexg'xCointoEnum,并返回硬币值以及更新的生成器。

  • random描述了如何仅从生成器生成随机硬币,而不将范围作为输入。它使用给定的生成器在minBound( Heads) 和maxBound( )之间生成抛硬币。Tailsg

coins是一个IO动作,它创建一个新的标准随机生成器newStdGen,然后从该生成器生成一个无限的随机投币列表(流)randoms g :: [Coin]。它用于take获取该列表的前 10 个元素并使用print.

r类似于coins,但也通过函数运行硬币抛掷,该process函数返回一对硬币给它的数量 ( length cs) 和那些是Heads( length (filter (== Heads) cs)) 的数量;以及将display结果格式化为字符串百分比的函数。


推荐阅读