我很难理解这一点(我对Haskell还有点陌生),但我发现Text.JSON
包的文档有点令人困惑。基本上我有这样的数据记录类型:-
data Tweet = Tweet
{
from_user :: String,
to_user_id :: String,
profile_image_url :: String,
created_at :: String,
id_str :: String,
source :: String,
to_user_id_str :: String,
from_user_id_str :: String,
from_user_id :: String,
text :: String,
metadata :: String
}
我有一些JSON格式的tweet符合这种类型的结构。我正在努力解决的问题是如何将上面的Map到从下面的代码返回的内容
decode tweet :: Result JSValue
上面的数据类型。我知道我应该创建一个instance JSON Tweet
的示例,但我不知道从哪里开始。
任何提示将不胜感激,谢谢!
4条答案
按热度按时间osh3o9ms1#
我建议您使用新的aeson包而不是json包,因为前者性能更好。下面是如何使用aeson将JSON对象转换为Haskell记录:
然后使用
Data.Aeson.json
得到一个attoparsec解析器,它将ByteString
转换为Value
。在Value
上调用fromJSON
,试图将其解析到记录中。请注意,这两个步骤中涉及两个不同的解析器,一个Data.Attoparsec.Parser
解析器用于将ByteString
转换为通用JSONValue
,然后一个Data.Aeson.Types.Parser
解析器用于将JSON值转换为记录。请注意,这两个步骤都可能失败:ByteString
不是有效的JSON值,第一个解析器可能会失败。fromJSON
实现中提到的字段之一,则第二个解析器可能会失败。aeson包更喜欢新的Unicode类型
Text
(在text包中定义),而不是更老的String
类型。Text
类型比String
具有更高的内存效率,并且通常性能更好。我建议您将Tweet
类型更改为使用Text
而不是String
。如果您需要在
String
和Text
之间进行转换,请使用Data.Text
中定义的pack
和unpack
函数。注意,这样的转换需要O(n)时间,所以尽可能避免它们(即始终使用Text
)。vtwuwzda2#
您需要为您的类型编写一个
showJSON
和readJSON
方法,该方法使用JSON格式构建Haskell值。JSON包将负责将原始字符串解析为JSValue
。你的tweet很可能是一个
JSObject
,包含一个字符串Map。show
查看JSObject,查看字段的布局。JSObject
上使用get_field
查找每个字段。fromJSString
从JSString
获取常规Haskell字符串。一般来说,你需要的是,
注意,我使用的是相当酷的通配符语言扩展。
如果没有JSON编码的示例,我就没有什么可提供的建议了。
您可以通过示例找到JSON编码的示例示例
kjthegm63#
导入Data.JSon.Generic和Data.Data,然后将deriving(Data)添加到您的记录类型,然后尝试在tweet上使用decodeJSON。
wlsrxk514#
我支持@tibbe的回答。但是,我想添加如何在提供的JSON中缺少参数时提供默认值。
在tibbe的回答中,你可以这样做:
这将在解析JSON时使用默认参数。