[英]Getting random numbers from non-monadic functions
因此,我的目标是能够调用非一元函数并使其返回随机值。
getNums :: [Int] -- this only works when the type signature is "IO [Int]"
getNums = getListFromIO 10
getListFromIO :: Int -> IO [Int]
getListFromIO n = do
gen <- newStdGen
return $ generateList n gen
generateList :: Int -> StdGen -> [Int]
generateList n gen = take n $ randomRs (1,9) $ gen
如果我调用getListFromIO
,一切都很好。 我得到了我宝贵的整数随机列表,并且每次都不同。 但是每个调用它的函数都必须使用IO [Int]
它的类型签名。 我不要
如何构造此结构,以便能够获得[Int]
类型的随机数列表?
您不能,不应该也不需要这样做。
您声称所有使用getNums :: IO [Int]
函数的类型都必须具有IO
。 这是不正确的。 您可以通过多种方式使用IO [Int]
操作计算的[Int]
值,例如:
main = do
ints <- getNums -- ints is now of type [Int]
return (map (+1) ints) -- map (+1) does not have IO in its type.
这是引入Functor
, Applicative
和Monad
类型类的原因之一:当您希望避免在任何地方处理IO
时,提供一种一致的方式来处理IO [Int]
类的东西。
IO的目的恰恰是不允许纯代码产生副作用。 所有非纯代码都必须在IO monad中运行。 随机性还基于状态或从外部资源读取(全局状态)。 因此,没有黑客,您尝试的事情是不可能的。 我强烈敦促您不要使用任何黑客手段。 这些黑客完全绕过了类型系统提供的安全性; 仅应将它们限制在本地安全的hack上,主要是在类型系统不是明智的且需要令人信服的情况下。 但事实并非如此-故意使一个纯函数表现得像一个非纯函数,绝不是一个本地化的技巧,因为任何调用它的代码都将继承损坏的语义,而无法跟踪纯函数的结束位置和非纯函数。纯度开始。
最好将代码重新设计为不需要在纯代码中生成随机数。 只需从驻留在IO中的代码层次结构的高层传递随机性即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.