如何在Haskell中结合使用fromList与System.Random.mkStdGen
实现步骤
- 第一步:引入必要依赖和模块
项目中引入MonadRandom和random两个依赖后,在代码头部导入对应模块:import Control.Monad.Random (Rand, evalRand, fromList) import System.Random (StdGen, mkStdGen) - 第二步:构造带权重的待选列表
按照fromList的参数要求构造[(a, Rational)]类型的列表,权重值越大对应元素被抽中的概率越高,示例如下:-- 示例:三种元素权重分别为1、2、3,抽中概率为1/6、2/6、3/6 weightList :: [(String, Rational)] weightList = [("选项A", 1), ("选项B", 2), ("选项C", 3)] - 第三步:生成随机数种子生成器
调用mkStdGen传入整数种子得到StdGen类型的随机数生成器:-- 示例:使用10086作为随机种子 gen :: StdGen gen = mkStdGen 10086 - 第四步:执行随机抽样计算
Rand StdGen类型已经天然满足fromList要求的MonadRandom约束,你找到的MonadInterleave实例是RandT的附加能力,不影响基础的随机抽样逻辑,直接用evalRand把抽样计算和生成器结合运行即可:main :: IO () main = do let result = evalRand (fromList weightList) gen print result
如果需要多次抽样或者在IO monad中使用,也可以直接用RandT包装IO,示例如下(需要额外导入Control.Monad (replicateM)):
import Control.Monad.Random (RandT, evalRandT, fromList) import System.Random (newStdGen) import Control.Monad (replicateM) main :: IO () main = do -- 直接用系统熵生成随机生成器,不需要手动指定种子 gen <- newStdGen -- 执行10次抽样 results <- evalRandT (replicateM 10 $ fromList weightList) gen print results
内容的提问来源于stack exchange,提问作者Kwaggy
相关产品推荐
相关产品推荐

