[theory] 一个有关 Haskell 随机数的问题
Lich_Ray
2007-08-04
其实应该问“一个有关 Haskell Time 的问题”,只是因为需要用 Time 来作随机数种子。Haskell 的 Time 好像都是 Monad 包装的,只能在 IO 环境下用。我现在不想使用 IO 环境就是那个 do 什么的,想用类似 random 的延续风格的 Time,有这样的调用吗?如果标准库里没有,有什么办法能使数据脱离 IO Monad,即把类似 IO Int 的类型转成 Int 版本?
|
|
cookoo
2007-08-05
Random库里的newStdGen就是根据时间生成random seed的,再传给randomRs或别的随机序列生成器就可以了。延续风格的Time?不太明白,怎么取当前时间呢?把Time理解成side effect很直观。
|
|
Lich_Ray
2007-08-05
newStdGen :: IO StdGen
怎么才能脱离 Monad 环境啊,郁闷的一腿艾! 事实是这样,我写了一个列表乱序的例程: -- 排除下标为 n 的项 except ls n = take n ls ++ (drop n (tail ls)) rand [] _ = [] -- 解释一个列表和一个 gen 为参数 rand ls g = ls !! i : (rand (ls `except` i) gen) where (i, gen) = randomR (0::Int, (length ls) - 1) g -- 这里的 randomR 就是延续风格的,压值同时再给出下一个算子 怎样做才能不在 IO 环境下获得一个 gen 呢? |
|
cookoo
2007-08-06
哦,原来你指的是randomR,这个是个pure的辅助函数,本身并不产生“随机性”,只要给的seed一样,出来的新seed总是一样。
问题是seed的产生即随机性的产生其本身必然是个side effect,你说呢?我觉得这个是不可能绕过IO monad的。 |
|
Lich_Ray
2007-08-06
如果有已经被延续风格包装过的 Timer 就 OK 了,但貌似没有。
还是 Haskell 的前身 Miranda 好用,将 call/cc 进行到底。 另外提一个无关的事情:上面我给的程序太傻了,做个快的: -- 这个函数很精彩的说~ explode [x] 0 = (x, []) explode (x:xs) n | n == 0 = (x, xs) | otherwise = (a, x:b) where (a, b) = explode xs (n-1) rand [] _ = [] rand ls g = x : (rand xs gen) where (x, xs) = ls `explode` i (i, gen) = randomR (0::Int, (length ls) - 1) g 嗯,以后就不改写尾递归了,那会使代码变丑滴! |