繁体   English   中英

从非一元函数获取随机数

[英]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.

这是引入FunctorApplicativeMonad类型类的原因之一:当您希望避免在任何地方处理IO时,提供一种一致的方式来处理IO [Int]类的东西。

IO的目的恰恰是不允许纯代码产生副作用。 所有非纯代码都必须在IO monad中运行。 随机性还基于状态或从外部资源读取(全局状态)。 因此,没有黑客,您尝试的事情是不可能的。 我强烈敦促您不要使用任何黑客手段。 这些黑客完全绕过了类型系统提供的安全性; 仅应将它们限制在本地安全的hack上,主要是在类型系统不是明智的且需要令人信服的情况下。 但事实并非如此-故意使一个纯函数表现得像一个非纯函数,绝不是一个本地化的技巧,因为任何调用它的代码都将继承损坏的语义,而无法跟踪纯函数的结束位置和非纯函数。纯度开始。

最好将代码重新设计为不需要在纯代码中生成随机数。 只需从驻留在IO中的代码层次结构的高层传递随机性即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM