我正在尝试将对象序列化为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"}
我在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)
哦不!
*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)
两个问题:
答案 0 :(得分:7)
您可以使用Data.Aeson.Text.encodeToLazyText直接将JSON编码为惰性Text
值。
{-# LANGUAGE DeriveGeneric #-}
import Data.Aeson.Text (encodeToLazyText)
...
I.writeFile "myfile.json" (encodeToLazyText meowmers)
bytestring
是二进制数据的类型 - 不一定是文本。要在bytestring中表示文本数据,您需要使用UTF-8等编码对其进行编码。一旦你有一个bytestring(用UTF-8编码或任何格式有意义),你可以使用Data.ByteString
函数将它写入文件:
import qualified Data.ByteString.Lazy as BS
BS.writeFile "myfile.json" (encode meowmers)
要完成这项工作,您需要为Cat
类型指定一个ToJSON
实例,该实例指定如何使用JSON对其进行编码。您可以使用DeriveGeneric
扩展程序自动执行此操作:
data Cat = Cat { ... } deriving (Show, Generic)
instance ToJSON Cat
如果您需要更好地控制生成的JSON的样子,也可以手动执行此操作。
答案 1 :(得分:7)
所以,要解决所有问题(因为大部分工作已经完成)。你实际上有两个问题:
<?php
$to = "me@mydomain.com";
$subject = "Test Subject";
$txt = "Hello world!";
$headers = "From: hello@gmail.com" . "\r\n" .
"CC: anotherme@mydomain.com";
mail($to,$subject,$txt,$headers);
?>
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)
通过aeson
在字符串类型之间进行转换。这涉及问题1。
然后,我使用语言扩展程序encodeToLazyText
获取DeriveGeneric
的{{1}}实例,并将其与扩展程序Generic
结合使用以获取{的实例{1}} Cat
。该实例的魔力再次是part of aeson
。
运行此操作后,我会收到一个包含DeriveAnyClass
的新文件ToJSON
。
答案 2 :(得分:3)
将所有评论和答案汇总成一个(在此处归功于其他人,请接受他们的答案之一)。
Generic
和ToJSON
(或者如果您愿意,可以手动编写ToJSON
个实例)。这需要更多LANGUAGE
个pragma。text
和encodeToLazyText
或使用Data.ByteString.Lazy.writeFile
写出字节字符串。
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
import GHC.Generics
import Data.Aeson (encode,ToJSON(..))
import Data.Text.Lazy (Text)
import qualified Data.ByteString.Lazy as BS
data Cat = Cat { name :: Text
, age :: Int
} deriving (Show,Generic,ToJSON)
main =
do let meowmers = Cat {name = "meowmers", age = 1}
BS.writeFile "myfile.json" (encode meowmers)
导致:
tommd@HalfAndHalf /tmp% runhaskell so.hs
tommd@HalfAndHalf /tmp% cat myfile.json
{"age":1,"name":"meowmers"}