【发布时间】:2010-04-01 06:21:39
【问题描述】:
我尝试编写一个基于数字类的随机数生成器实现。我还在那里添加了 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
RandomMonad.hs 文件内容来了:
-- RandomMonad.hs --
module RandomMonad where
import Control.Monad
import System.Random
import Data.List
data RandomGen g => Rand g a = Rand (g ->(a,g)) | RandZero
instance (Show g, RandomGen g) => Monad (Rand g)
where
return x = Rand (\g ->(x,g))
(RandZero)>>= _ = RandZero
(Rand argTransformer)>>=(parametricRandom) = Rand funTransformer
where
funTransformer g | isZero x = funTransformer g1
| otherwise = (getRandom x g1,getGen x g1)
where
x = parametricRandom val
(val,g1) = argTransformer g
isZero RandZero = True
isZero _ = False
instance (Show g, RandomGen g) => MonadPlus (Rand g)
where
mzero = RandZero
RandZero `mplus` x = x
x `mplus` RandZero = x
x `mplus` y = x
getRandom :: RandomGen g => Rand g a ->g ->a
getRandom (Rand f) g = (fst (f g))
getGen :: RandomGen g => Rand g a ->g -> g
getGen (Rand f) g = snd (f g)
当我运行 ghci 解释器时,并给出以下命令
getRandom y (mkStdGen 2000000000)
我可以在我的计算机上看到内存溢出 (1G)。这是意料之外的,如果我删除一名守卫,它的工作速度非常快。为什么在这种情况下它运行得太慢了?
我做错了什么?
【问题讨论】:
-
不相关:Haskell 中的标准随机数生成器 很慢。改用 System.Random.Mersenne。
-
好的。但是,当我尝试 (System.Random) 时,为什么要使用这么多内存?我认为,>>=定义中的问题。是尾递归吗?我认为是。
-
我还不知道——但你可以使用
guard (a /= 1 && a /= 2)。 -
当然。但是,当我的“做”声明中有许多警卫时,我就有动力使用警卫。
标签: performance haskell random monads