我想做一个Haskell函数,它可以从给定的列表中挑选出一个随机数。我的类型签名是:
randomPick :: [a] -> a
我该怎么办?
发布于 2010-05-28 10:14:53
您所描述的内容不能在纯函数代码中完成。
纯函数代码意味着您每次都会为相同的输入获得相同的输出。由于根据定义,随机化函数为相同的输入提供不同的输出,这在纯函数代码中是不可能的。
除非您传递一个额外的值,如@camccann's answer中所述。从技术上讲,它甚至不需要像RNG那样高级,这取决于您的需求。你可以传递一个整数,然后乘以10,再减去3(或其他任何东西),然后取它的模来得到你的索引。那么你的函数仍然是纯的,但是你可以直接控制随机性。
另一种选择是使用RandomRIO
在一个范围内生成一个数字,然后您可以使用该数字从列表中选择一个索引。这将要求您进入IO monad。
发布于 2010-05-28 16:52:16
如果你想在纯函数代码中使用随机数生成器,而不是显式地传递生成器状态,那么你可以使用状态monad (或者monad transformer)并隐藏管道。状态monad仍然是参照透明的,并且它是安全和正常的转义状态monad。如果你想要真正的局部可变状态,在外部是纯函数的,你也可以使用ST monad。
下面是我写的一些有用的代码,有时也会用到:
rand :: (Random a, RandomGen g, MonadState g m) => a -> a -> m a
rand lo hi = do
r <- get
let (val, r') = randomR (lo, hi) r
put r'
return val
https://stackoverflow.com/questions/2926267
复制相似问题