我正在尝试编写一个功能,从可以挑选的所有可能的卡中挑选一张随机卡。卡片属于我声明的名为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的初学者和一般的函数式编程。
答案 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