[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

嗯,以后就不改写尾递归了,那会使代码变丑滴!
Global site tag (gtag.js) - Google Analytics