Я попытался написать одну генерацию случайных чисел, основанную на классе чисел. Я также добавляю экземпляр Monad и MonadPlus.Очень медленные охранники в моей монадической случайной реализации (haskell)
Что означает «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)
I может видеть переполнение памяти на моем компьютере (1G). Этого не ожидается, и если я удалю одного охранника, он работает очень быстро. Почему в этом случае он работает слишком медленно?
Что я делаю неправильно?
Неприменимо: стандартный генератор случайных чисел в Haskell * является медленным. Вместо этого попробуйте System.Random.Mersenne. – kennytm
Хорошо. Но почему так много памяти используется, когда я пытаюсь (System.Random)? Я думаю, проблема в >> = определении. Является ли он рекурсивным? Я думаю, что это. – user306614
Я еще не знаю (но), но вы можете использовать 'guard (a/= 1 && a/= 2)'. – kennytm