这个问题已经回答了四年了,但我在Don Stewart的回答的评论中遇到了与gatoatigrado相同的问题。 put
方法按照广告方式工作,但get
读取整个输入。我认为问题在于案例陈述Stream xs <- get
中的模式匹配,它必须确定在返回之前剩余的get
是否为Stream a
。
我的解决方案中使用的示例中Data.Binary.Get为起点:
import Data.ByteString.Lazy(toChunks,ByteString)
import Data.Binary(Binary(..),getWord8)
import Data.Binary.Get(pushChunk,Decoder(..),runGetIncremental)
import Data.List(unfoldr)
decodes :: Binary a => ByteString -> [a]
decodes = runGets (getWord8 >> get)
runGets :: Get a -> ByteString -> [a]
runGets g = unfoldr (decode1 d) . toChunks
where d = runGetIncremental g
decode1 _ [] = Nothing
decode1 d (x:xs) = case d `pushChunk` x of
Fail _ _ str -> error str
Done x' _ a -> Just (a,x':xs)
[email protected](Partial _) -> decode1 k xs
使用注意事项的getWord8
这是读取编码的[]
和:
从用于流的put
定义所得实例。另请注意,由于getWord8忽略了编码的[]和:符号,因此此实现不会检测列表的结尾。我的编码文件只是一个单一的列表,所以它的工作原理,但否则你需要修改。
在任何情况下,这个decodes
在访问头部元素和最后一个元素的情况下都运行在恒定内存中。
你能为Binary写一个流式实例吗?编写一个chunk-wise(渴望)编码器相对容易,它一次编写多组* n *个元素。 – 2011-06-01 17:38:00
噢,我并不认为这很简单。我主要想知道它是否已经完成。如果不是,我是否应该从现有的抽象或类型类? – mightybyte 2011-06-01 17:46:19
没有我知道的。尽管你可能有幸在Hackage上寻找可搜索的文件API。 – 2011-06-01 17:57:17