Haskell随机生成器......如何使用更容易?

时间:2011-09-07 05:45:03

标签: haskell random

我遇到与Haskell Random generator相关的问题。在大学里,我必须一直处理Java,所以现在我已经腐败了。 我正在Haskell开发一款游戏,现在我面临着“做某事的机会”这样的事情,而这种机会需要像Int -> Bool。在Java中,我会完成

new Random().nextInt(100) 

然后,问题解决了! 在Haskell中,我必须在monad IO中选择一些东西或者使用种子。这些都不是我想要的。我真的不想在我的纯模型中使用IO monad,种子很难用,因为我每次都需要记住我的新种子......

是否有像Java的Random这样简单的东西?

4 个答案:

答案 0 :(得分:12)

信不信由你,你必须在Haskell中使用不同于Java的方法。有几个软件包可以帮助您,但是 必须在脑海中采取不同的态度才能成功使用它们。以下是一些提示:

Hackage's package list上搜索“随机”一词会出现更多,更具体的包,以满足更具体的需求。

答案 1 :(得分:7)

抱歉,你必须忍受这一点。 如何在纯函数式语言中使用函数,在每次调用时为您提供不同的值?答案是:它不能 - 只有IO-Monad或类似于状态monad的东西,你可以传递你的种子(并且每次都没有相同的输入)可以存在这样的事情。

您也可以看一下这个问题“How can a time function exist in functional programming?”,因为它与您的方向相同。

答案 2 :(得分:2)

有点不直观,既不输入也不输出的东西需要像处理那样处理。假设您将其定义如下:

random100 = unsafePerformIO $ randomRIO (1, 100) -- This will not work!

这确实会给你一个随机数 - 在a way。您真正需要的是一种编码方式,每次都需要伪随机数。这意味着信息需要从一个随机数生成到下一个。大多数语言都忽略了这个“小细节”,但Haskell强迫你注意。当你发现自己在多线程环境中正确地重现你的伪随机结果时,你可能会感谢Haskell。

您可以通过多种方式建立这些连接,其中大部分已经提到过。如果你不愿意使用monad:请注意,以monadic形式(但不使用IO!)代码通常是一件好事。在路上,您可能会遇到需要更多monad功能的情况,例如配置阅读器 - 然后所有基础工作都已完成。

答案 3 :(得分:2)

我认为,“你将不得不忍受”,既不有用也不正确。这实际上取决于您使用的抽象。如果你的应用程序自然地绑定到monad,那么使用monadic随机数生成器是有意义的,这与Java的随机数生成器一样方便。

对于使用现代抽象的游戏,您的应用程序自然会受到功能反应式编程(FRP)的约束,其中生成随机数根本不是问题,并且不需要您明确地传递生成器。使用netwire库的示例:

movingPoint :: MonadIO m => (Double, Double) -> Wire m a (Double, Double)
movingPoint x0 =
    proc _ -> do
        -- Randomly fades in and out of existence.
        visible <- wackelkontakt -< ()
        require -< (visible, ())

        -- 'rnd' is a random value between -1 and 1.
        rnd <- noise1 -< ()

        -- dx is the velocity.
        let dx = (sin &&& cos) (rnd * pi)

        -- Integration of dx over time gives us the point's position.
        -- x0 is the starting point.
        integral x0 -< dx

有没有办法更简单,更简洁地表达这一点?我猜不会。 FRP也证明了Zhen的评论是错误的。它可以纯粹处理用户输入。