haskell - 为 MWC (Haskell) 编写一个 MonadRandom 实例

标签 haskell monads

我希望能够使用 MWC random number generator与 random-fu,因此需要实现 MonadRandom 的实例。我的尝试是将 Reader (Gen (PrimState m)) v 视为 MonadRandom v。但是,以下失败:

$(monadRandom [d|
  instance (PrimMonad m) => MonadRandom (Reader (MWC.Gen (PrimState m))) where
    getRandomWord16 = ask >>= MWC.uniform
    getRandomWord32 = ask >>= MWC.uniform
    getRandomWord64 = ask >>= MWC.uniform
  |])

错误:

Illegal type synonym family application in instance:
  Reader (MWC.Gen (PrimState m_ahwD))
In the instance declaration for
  ‘MonadRandom (Reader (MWC.Gen (PrimState m_ahwD)))’

我做错了什么?

最佳答案

基于其他贡献者已经说过的话

{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE GADTs             #-}
{-# LANGUAGE FlexibleInstances #-}

import Data.Random
import Data.Random.Source
import qualified System.Random.MWC as MWC
import Control.Monad.Reader
import Control.Monad.Primitive

$(monadRandom [d|
  instance (PrimMonad m, s ~ PrimState m) => MonadRandom (ReaderT (MWC.Gen s) m) where
    getRandomWord16 = ask >>= lift . MWC.uniform
    getRandomWord32 = ask >>= lift . MWC.uniform
    getRandomWord64 = ask >>= lift . MWC.uniform
  |])

testUniform :: MonadRandom m => Int -> m [Double]
testUniform n = replicateM (fromIntegral n) (sample stdUniform)

n :: Int
n = 10^7

main :: IO ()
main = do
    seed <- MWC.create
    xs <- runReaderT (testUniform n) seed
    print (sum xs / fromIntegral n)

但是效果不是很好

./RandomFuMWC +RTS -s
0.5000432391067587
   3,286,220,896 bytes allocated in the heap
   2,427,475,880 bytes copied during GC
     600,186,048 bytes maximum residency (12 sample(s))
     100,510,656 bytes maximum slop
            1249 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      5942 colls,     0 par    1.06s    1.13s     0.0002s    0.0013s
  Gen  1        12 colls,     0 par    0.82s    1.23s     0.1024s    0.5787s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    1.47s  (  1.39s elapsed)
  GC      time    1.87s  (  2.36s elapsed)
  EXIT    time    0.01s  (  0.09s elapsed)
  Total   time    3.35s  (  3.84s elapsed)

  %GC     time      56.0%  (61.3% elapsed)

  Alloc rate    2,242,365,923 bytes per MUT second

  Productivity  44.0% of total user, 38.3% of total elapsed

关于haskell - 为 MWC (Haskell) 编写一个 MonadRandom 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25886434/

相关文章:

haskell - Haskell 中的 print 是纯函数吗?

haskell - 如何使文件 I/O 更具事务性?

parsing - 如何在 Parsec ParserT monad 中表达解析逻辑

f# - 消除我通过类似、单子(monad)之类的东西传递的显式状态

haskell加入多级monad

haskell - 类型签名需要库未导出的类型

scala - 等效于 Scala 中的 Haskell do-notation 或 F# 计算表达式?

haskell - 如何使用 map 和过滤器实现列表理解?

Haskell:从 IO [[String]] 生成 HaTeX 输出

haskell - Functor -> Applicative -> Monad 层次结构的意义是什么