小编hpa*_*eco的帖子

Haskell:懒惰的`Control.Monad.ST.Lazy` monad是多么懒惰?

我一直在试验严格和懒惰的STmonad,我不清楚每个人的懒惰程度.例如,使用惰性Control.Monad.State.Lazymonad我们可以写:

main = print $ (flip evalState) "a" $ do
    forever $ put "b"
    put "c"
    get
Run Code Online (Sandbox Code Playgroud)

这很好,输出"c".双重地,严格Control.Monad.State.Strict变体的相同代码将put "b"永远运行,并挂起.

直观地说,我希望STmonad 具有相同的二元性.也就是说,给出代码:

main = print $ S.runST $ do
        r <- newSTRef "a"
        forever $ writeSTRef r "b"
        writeSTRef r "c"
        readSTRef r
Run Code Online (Sandbox Code Playgroud)

Control.Monad.ST.Lazy应该输出"c",同时Control.Monad.ST.Strict应该挂起.但是,它们都无限循环.我认为这是有正当理由的,例如:向后读,在调用r最后一个时尚未分配引用writeSTRef.但它感觉我们可以做得更好.

haskell

10
推荐指数
1
解决办法
439
查看次数

Haskell:IORefs的表现

我一直在尝试在Haskell中编码一个需要使用大量可变引用的算法,但与纯粹的惰性代码相比,它(可能并不奇怪)非常慢.考虑一个非常简单的例子:

module Main where

import Data.IORef
import Control.Monad
import Control.Monad.Identity

list :: [Int]
list = [1..10^6]

main1 = mapM newIORef list >>= mapM readIORef >>= print
main2 = print $ map runIdentity $ map Identity list
Run Code Online (Sandbox Code Playgroud)

在我的机器上运行GHC 7.8.2,main1需要1.2秒并使用290MB内存,而main2只需0.4秒,仅使用1MB.是否有任何阻止这种增长的技巧,特别是在太空?我经常需要IORef非原始类型的s Int,并且假设一个人IORef会像常规thunk一样使用额外的指针,但我的直觉似乎是错误的.

我已经尝试了一个带有解压缩的专用列表类型IORef,但没有显着差异.

performance haskell ioref

8
推荐指数
2
解决办法
1396
查看次数

标签 统计

haskell ×2

ioref ×1

performance ×1