Json Aeson惰性解析器

Json Aeson惰性解析器,json,parsing,haskell,aeson,Json,Parsing,Haskell,Aeson,Aeson库提供了两种json解析器:严格的和惰性的。懒惰者声称可以节省时间,但却可以创建thunks,而严格者则可以节省空间并占用更多的时间(如果数据不经常访问的话)。我有下面的玩具程序来查看它们之间的差异,但配置文件是相同的: import Data.Aeson import Data.ByteString as B import Data.Attoparsec.ByteString as P import System.Environment main = do [fn] <

Aeson库提供了两种json解析器:严格的和惰性的。懒惰者声称可以节省时间,但却可以创建thunks,而严格者则可以节省空间并占用更多的时间(如果数据不经常访问的话)。我有下面的玩具程序来查看它们之间的差异,但配置文件是相同的:

import Data.Aeson
import Data.ByteString as B
import Data.Attoparsec.ByteString as P
import System.Environment

main = do
    [fn] <- getArgs
    fc <- B.readFile fn
    let r = P.parse json' fc
    case r
      of Done _ _ -> print ":)"
         _   -> print ":("
为什么懒惰版本不能在第一个程序中节省时间,在第二个程序中浪费空间?有没有一个例子,其中一个解析器显然获胜

更新:以下是我最近对来自JSON的
进行的实验,它也未能区分
解码
解码

Data Weirder = Weirder

instance FromJSON Weirder where
    parseJSON (Number n) = return $! undefined -- $! trace "weirdercalled" Weirder -- `seq` Weirder

main = do
    [fn] <- getArgs
    fc <- B.readFile fn
    let Just rs = decode fc :: Maybe [Weirder]
    print $ length rs
数据古怪=古怪
实例FromJSON-Weirder在哪里
parseJSON(数字n)=返回$!未定义--$!跟踪“古怪的”古怪--`seq`古怪的
main=do

[fn]首先是一个明显的问题:你的文件大到哪里可以观察到解析?@Carsten我试过大小为20M的json文件,它够大吗?
json'
没有有趣的计算(只应用构造函数),因此没有(足够)计算延迟懒惰。做一些更有趣的事情,比如解析一个数字并返回
last[n..maxBound]
作为解析的值,您将看到差异。(我没有把这变成一个答案,因为每次我触摸aeson时,我都会迷失在一个迷宫中,迷宫中有扭曲的
解析器
类型和
解析
函数,它们都很相似。)@DanielWagner你确定吗?aeson中的
构造非常严格。aeson解析函数报告错误;为此,它必须检查元素是否正确,并构建aeson
,然后进行
parseJSON
和自定义解析。在我看来,那里没有剩余的懒惰。@ondra我想我们是一致的!你说“没有剩余的懒惰”,我说“没有足够的计算让懒惰延迟”。如果我能肯定你在问什么?
Data Weirder = Weirder

instance FromJSON Weirder where
    parseJSON (Number n) = return $! undefined -- $! trace "weirdercalled" Weirder -- `seq` Weirder

main = do
    [fn] <- getArgs
    fc <- B.readFile fn
    let Just rs = decode fc :: Maybe [Weirder]
    print $ length rs