How to force strict evaluation of a sequence of ByteString

≡放荡痞女 提交于 2019-12-24 10:14:46

问题


I have the following Haskell type definition:

import Data.Sequence(Seq, length)
import Data.ByteString.UTF8(ByteString)

type StringSeq = Seq ByteString

I have expressions of type StringSeq for which I would like to force strict evaluation with deepseq. So I need to define instances of NFData. I did the following:

import Control.DeepSeq(NFData, deepseq)

instance NFData ByteString

instance NFData a => NFData (Seq a) where
  rnf s = rnf (length s)

So I compute the length of a sequence to force evaluation of the sequence itself. This seems to work but is this the correct implementation? Are there better ones? Does computing the length of a sequence introduce too much overhead?


回答1:


You can define a monad for strictness

data Strict a = Strict {fromStrict :: !a}
instance Monad Strict where
   return = Strict
   (Strict x) >>= f = f x

Okay, I don't think this actually obeys the monad laws, but it is close enough. Using this you can define a function

srnf = Strict . rnf 

such that

instance NFData a => NFData (Seq a) where
  rnf s = fromStrict $ (mapM srnf s) >> return ()

Untested, but should work (and it should work for all Traversable data structures).




回答2:


Computing length is not enough, you need to compute the normal forms of the content of a sequence. I suggest you to use seqFoldable from Control.Seq which allows you to force any foldable structure. Then you can call simply

mySeq `using` seqFoldable rdeepseq

or define

instance NFData a => NFData (Seq a) where
    rnf = seqFoldable rdeepseq


来源:https://stackoverflow.com/questions/13963102/how-to-force-strict-evaluation-of-a-sequence-of-bytestring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!