从自我声明的数据类型的值列表中选取一个随机值

时间:2013-10-31 14:06:19

标签: haskell random

我正在尝试编写一个功能,从可以挑选的所有可能的卡中挑选一张随机卡。卡片属于我声明的名为rank的类型。我的代码如下所示:

data Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
            | Jack | Queen | King
            deriving(Eq, Ord, Bounded, Enum, Show, Read)

pickCard :: Rank
pickCard = error "How should I pick a random card here? :("

当然我希望这个函数做的是从列表[Ace .. King]中选择一个随机值我该怎么做?请记住,我是Haskell的初学者和一般的函数式编程。

1 个答案:

答案 0 :(得分:6)

在Haskell中,函数是引用透明的,这意味着如果你将相同的东西放入函数中,你就会得到同样的东西。所以没有像

这样的功能
random :: () -> Int

每次使用时都会返回不同的结果。有几种方法可以解决这个问题,最简单的方法是使用现有的随机设施。

import System.Random -- requires the random package from Hackage

instance Random Rank where -- Describes how to choose random card
  randomR (a,b) = over toEnum . randomR (fromEnum a, fromEnum b)
    where over f (a, b) = (f a, b)
  random = randomR (minBound, maxBound)

pickCard :: IO Rank
pickCard = randomIO

-- Or we can pass in a source of randomness and pass out the new one
pickCard :: RandomGen g => g -> (Rank, g)
pickCard = random