我正在尝试将对象序列化为JSON字符串并将其写入文件.
在python中,我会做类似的事情:
>>> meowmers = {"name" : "meowmers", "age" : 1}
>>> import json
>>> with open("myfile.json","wb") as f
json.dump(meowmers, f)
$ cat myfile.json
{"age": 1, "name": "meowmers"}
Run Code Online (Sandbox Code Playgroud)
我在Haskell看这个
$ stack ghci
{-# LANGUAGE OverloadedStrings #-}
:set -XOverloadedStrings
import GHC.Generics
import Data.Aeson as A
import Data.Text.Lazy as T
import Data.Text.Lazy.IO as I
:{
data Cat = Cat {
name :: Text
, age :: Int
} deriving Show
:}
let meowmers = Cat {name = "meowmers", age = 1}
writeFile "myfile.json" (encode meowmers)
Run Code Online (Sandbox Code Playgroud)
不好了!
*A T I GHC.Generics> I.writeFile "myfile2.json" (encode meowmers)
<interactive>:34:29:
Couldn't match expected type ‘Text’
with actual type ‘bytestring-0.10.6.0:Data.ByteString.Lazy.Internal.ByteString’
In the second argument of ‘I.writeFile’, namely ‘(encode meowmers)’
In the expression: I.writeFile "myfile2.json" (encode meowmers)
Run Code Online (Sandbox Code Playgroud)
两个问题:
您可以Text使用Data.Aeson.Text.encodeToLazyText直接将JSON编码为延迟值.
{-# LANGUAGE DeriveGeneric #-}
import Data.Aeson.Text (encodeToLazyText)
...
I.writeFile "myfile.json" (encodeToLazyText meowmers)
Run Code Online (Sandbox Code Playgroud)
A bytestring是二进制数据的类型 - 不一定是文本.要在bytestring中表示文本数据,您需要使用UTF-8等编码对其进行编码.一旦你有一个bytestring(用UTF-8编码或任何格式有意义),你可以使用Data.ByteString函数将它写入文件:
import qualified Data.ByteString.Lazy as BS
BS.writeFile "myfile.json" (encode meowmers)
Run Code Online (Sandbox Code Playgroud)
要使这项工作,您需要为您的Cat类型提供一个ToJSON实例,指定如何在JSON中对其进行编码.您可以使用DeriveGeneric扩展名自动执行此操作:
data Cat = Cat { ... } deriving (Show, Generic)
instance ToJSON Cat
Run Code Online (Sandbox Code Playgroud)
如果您需要更好地控制生成的JSON的外观,也可以手动执行此操作.
因此,要解决所有问题(因为大部分工作已经完成).你实际上有两个问题:
ToJSON声明的实例Cat这是一个依赖于最新版本aeson和text(对我来说是aeson-1.0.0.0和的)的工作示例text-1.2.2.1.
{-# LANGUAGE OverloadedStrings, DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics
import Data.Text.Lazy (Text)
import Data.Text.Lazy.IO as I
import Data.Aeson.Text (encodeToLazyText)
import Data.Aeson (ToJSON)
data Cat = Cat { name :: Text, age :: Int } deriving (Show, Generic, ToJSON)
meowmers = Cat { name = "meowmers", age = 1 }
main = I.writeFile "myfile.json" (encodeToLazyText meowmers)
Run Code Online (Sandbox Code Playgroud)
正如你可以从导入中看到的那样,我依赖于aeson在字符串类型之间进行转换encodeToLazyText.这涉及问题1.
然后,我使用语言扩展DeriveGeneric来获取Generic实例Cat,并将其与扩展一起使用DeriveAnyClass以获取ToJSONfor 的实例Cat.该实例的魔力再次成为其中的一部分aeson.
运行它,我得到一个myfile.json包含{"age":1,"name":"meowmers"}在其中的新文件.
| 归档时间: |
|
| 查看次数: |
1071 次 |
| 最近记录: |