Podoba mi się pakiet mersenne-random-pure64. Na przykład można go używać tak, aby generować nieskończoną leniwy strumień losowych deblu z wartością początkową:
import Data.Word (Word64)
import Data.List (unfoldr)
import System.Random.Mersenne.Pure64
randomStream :: (PureMT -> (a, PureMT)) -> PureMT -> [a]
randomStream rndstep g = unfoldr (Just . rndstep) g
toStream :: Word64 -> [Double]
toStream seed = randomStream randomDouble $ pureMT seed
main = print . take 10 $ toStream 42
użyciu System.Random (randoms)
Można uzyskać podobny wynik z wbudowane randoms
funkcji, które jest krótsze i bardziej ogólny (Dzięki ehird za wskazujące, że z):
import System.Random (randoms)
import System.Random.Mersenne.Pure64 (pureMT)
main = print . take 10 $ randomdoubles where
randomdoubles :: [Double]
randomdoubles = randoms $ pureMT 42
czyni to wystąpienie MonadRandom
Po przeczytaniu około MonadRandom
ciekawi mnie, jak uzyskać PureMT
działającej jako jego przykład. Po wyjęciu z pudełka nie działa, ponieważ PureMT
nie tworzy instancji RandomGen
's funkcji split
. Jednym ze sposobów, aby to zadziałało, jest owinięcie PureMT
w newtype
i napisanie niestandardowej instancji split
dla egzemplarza typu RandomGen
, dla którego istnieje domyślna instancja MonadRandom
.
import Control.Monad.Random
import System.Random.Mersenne.Pure64
getTenRandomDoubles :: Rand MyPureMT [Double]
getTenRandomDoubles = getRandoms >>= return . take 10
main = print $ evalRand getTenRandomDoubles g
where g = MyPureMT $ pureMT 42
newtype MyPureMT = MyPureMT { unMyPureMT :: PureMT }
myPureMT = MyPureMT . pureMT
instance RandomGen MyPureMT where
next = nextMyPureMT
split = splitMyPureMT
splitMyPureMT :: MyPureMT -> (MyPureMT, MyPureMT)
splitMyPureMT (MyPureMT g) = (myPureMT s, myPureMT s') where
(s',g'') = randomWord64 g'
(s ,g') = randomWord64 g
nextMyPureMT (MyPureMT g) = (s, MyPureMT g') where
(s, g') = randomInt g
+1 dla 'MonadRandom', to jest droga. – luqui
@hhird Co to jest tutaj wolne źródło losowości, które utrzyma go w czystości? ECC? –
@JFritsch: Pamiętaj, że czyste nie oznacza tylko braku IO. Czysta funkcja musi zawsze zwracać ten sam wynik z tymi samymi argumentami. Jedynym "źródłem losowości" jest generator lub _seed_ ('g' w sygnaturach typu). – hammar