gpt4 book ai didi

haskell - Rand monad 的 MonadFix 实例

转载 作者:行者123 更新时间:2023-12-04 22:36:32 25 4
gpt4 key购买 nike

我想从 System.Random.MWC.Monad 用 Rand monad 生成无限的数字流。如果这个 monad 有一个 MonadFix 实例,或者像这样的实例:

instance (PrimMonad m) => MonadFix m where
...

那么可以写:
runWithSystemRandom (mfix (\ xs -> uniform >>= \x -> return (x:xs)))

虽然没有。

我正在经历 MonadFix docs 但我没有看到实现这个实例的明显方法。

最佳答案

一个问题:您希望如何生成初始种子?

问题是 MWS 建立在“原始”包上,它只抽象了 IO 和严格(Control.Monad.ST.ST s)。它也不抽象惰性(Control.Monad.ST.Lazy.ST s)。

也许可以为“原始”提供实例来覆盖懒惰的 ST,然后 MWS 可能是懒惰的。

更新:我可以通过使用 strictToLazyST 来使用 Control.Monad.ST.Lazy 完成这项工作:

module Main where

import Control.Monad(replicateM)
import qualified Control.Monad.ST as S
import qualified Control.Monad.ST.Lazy as L
import qualified System.Random.MWC as A

foo :: Int -> L.ST s [Int]
foo i = do rest <- foo $! succ i
return (i:rest)

splam :: A.Gen s -> S.ST s Int
splam = A.uniformR (0,100)

getS :: Int -> S.ST s [Int]
getS n = do gen <- A.create
replicateM n (splam gen)

getL :: Int -> L.ST s [Int]
getL n = do gen <- createLazy
replicateM n (L.strictToLazyST (splam gen))

createLazy :: L.ST s (A.Gen s)
createLazy = L.strictToLazyST A.create

makeLots :: A.Gen s -> L.ST s [Int]
makeLots gen = do x <- L.strictToLazyST (A.uniformR (0,100) gen)
rest <- makeLots gen
return (x:rest)

main = do
print (S.runST (getS 8))
print (L.runST (getL 8))
let inf = L.runST (foo 0) :: [Int]
print (take 10 inf)
let inf3 = L.runST (createLazy >>= makeLots) :: [Int]
print (take 10 inf3)

关于haskell - Rand monad 的 MonadFix 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5365292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com