Performance 我的一元随机实现(haskell)中的速度非常慢

Performance 我的一元随机实现(haskell)中的速度非常慢,performance,haskell,random,monads,Performance,Haskell,Random,Monads,我试图基于数字类编写一个随机数生成器实现。我还添加了Monad和MonadPlus实例 “MonadPlus”是什么意思?我为什么添加这个实例?因为我想使用像这样的守卫: -- test.hs -- import RandomMonad import Control.Monad import System.Random x = Rand (randomR (1 ::Integer, 3)) ::Rand StdGen Integer y = do a <-x gu

我试图基于数字类编写一个随机数生成器实现。我还添加了Monad和MonadPlus实例

“MonadPlus”是什么意思?我为什么添加这个实例?因为我想使用像这样的守卫:

--  test.hs       --

import RandomMonad
import Control.Monad
import System.Random 

x = Rand (randomR (1 ::Integer, 3)) ::Rand StdGen Integer

y = do
 a <-x
 guard (a /=2) 
 guard (a /=1)
 return a
当我运行ghci解释器时,并给出以下命令

getRandom y (mkStdGen 2000000000)
我可以看到我的计算机(1G)内存溢出。这是意料之外的,如果我删除一个防护,它的工作速度会非常快。为什么在这种情况下它工作得太慢

我做错了什么?

你对
(>>=)
的定义肯定是错误的,但我无法指出哪里,因为它太复杂了!相反,我将用一个例子解释为什么不能正确定义它。考虑:

Rand (\g -> (42,g)) >>= const mzero
我们需要把这个
42
拿出来,所以我们需要一个
g
。从绑定的返回值中获取g,因此答案肯定是:

Rand (\g -> ...)
对于某些
,负责返回
(b,g)
对。既然我们有42个,我们可以计算
常数mzero 42
并发现我们有
RandZero
,但是我们从哪里得到
b
?它不存在(事实上,在本例中,它不可能是任何类型,因为表达式的类型是
forall b.Rand b

对你的单子来说,
RandZero
的目的是什么?你只是想说明一下可能的情况吗?我猜你是。在这种情况下,您可能更幸运地尝试实现这种类型:

你对
(>>=)
的定义肯定是错误的,但我不能指出哪里,因为它太复杂了!相反,我将用一个例子解释为什么不能正确定义它。考虑:

Rand (\g -> (42,g)) >>= const mzero
我们需要把这个
42
拿出来,所以我们需要一个
g
。从绑定的返回值中获取g,因此答案肯定是:

Rand (\g -> ...)
对于某些
,负责返回
(b,g)
对。既然我们有42个,我们可以计算
常数mzero 42
并发现我们有
RandZero
,但是我们从哪里得到
b
?它不存在(事实上,在本例中,它不可能是任何类型,因为表达式的类型是
forall b.Rand b

对你的单子来说,
RandZero
的目的是什么?你只是想说明一下可能的情况吗?我猜你是。在这种情况下,您可能更幸运地尝试实现这种类型:

如果我正确理解您的“单子”,则
(>>=)
无法关联。尝试定义

y' = do a <- do a' <- x
                guard (a' /= 2)
                return a'
        guard (a /= 1)
        return a
y'=do a如果我正确理解您的“单子”,则
(>>=)
无法关联。尝试定义

y' = do a <- do a' <- x
                guard (a' /= 2)
                return a'
        guard (a /= 1)
        return a

y'=做一个无关的事情:Haskell中的标准随机数生成器速度很慢。试试System.Random.Mersenne,好的。但是当我尝试(System.Random)时,为什么要使用这么多内存呢?我认为,问题在于>>=定义。它是尾部递归的吗?我想是的。我还不知道-但是你可以使用
守卫(a/=1&&a/=2)
。但是我的动机是在我的“do”语句中有很多警卫的时候使用警卫。不相关:Haskell中的标准随机数生成器很慢。试试System.Random.Mersenne,好的。但是当我尝试(System.Random)时,为什么要使用这么多内存呢?我认为,问题在于>>=定义。它是尾部递归的吗?我想是的。我还不知道-但是你可以使用
守卫(a/=1&&a/=2)
。但我的动机是在我的“行动”声明中有很多警卫的时候使用警卫。我意识到我的策略是错误的,现在我用liquid的策略来代替-这对我的目的是理想的。我意识到我的策略是错误的,现在我用liquid的策略代替-这对我的目的是理想的。