请注意,以下描述的问题不会发生在
aeson 1.4.7
(stack LTS-16.31
)。这可能与ghc 9.2.7
有关。
我注意到,如果我在
aeson
中定义一个简单的记录,然后导入它,记录“代码”标签现在在 encode
输出中被误认为是“正文”。它仅在作为模块导入时发生。
首先是一个简单的模块
Test1
:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell,DeriveGeneric #-}
{-# LANGUAGE Strict #-}
module Test1
where
import Data.Aeson.TH
import Data.Aeson
import GHC.Generics
import qualified Data.Text as T (Text)
data Rsp = Rsp { code::Int, tag :: T.Text, body:: T.Text } deriving (Show,Eq,Ord)
deriveJSON defaultOptions '' Rsp
现在,如果我在
ghci
和 encode
Rsp
中导入模块 - “code”标签现在被编码为“body”标签,它出现两次而不是一次:
ghci> import Test1
ghci> import Data.Aeson (encode)
ghci> encode $ Rsp (1::Int) "nyi" ""
"{\"body\":1,\"tag\":\"nyi\",\"body\":\"\"}"
我在调试从
aeson 1.4.7.1
(在 ghc 8.8.4
上,通过 Stack LTS-16.31
)迁移到 aeson 2.0.3.0
(在 ghc 9.2.7
上,通过 Stack LTS-20.13
)的迁移问题时发现了这一点。如果我不导入模块,而是直接在 ghci 中加载 Test1.hs
代码,就不会发生这种情况。
如果我删除
Strict
pragma,问题似乎就消失了。也许这里发生了一些对 ghc 9.2+
或 aeson
中的模板 haskell 推导是新的事情?
这是一个已在
2.1.1.0
中修复的错误,如 changelog 中所述:
在 TH 序列化中创建密钥时使用 unsafeDupablePerformIO 而不是不正确的 accursedUnutterablePerformIO。这修复了 TH 推导中的错误,例如当启用 Strict pragma 时。
因此,如果为
LTS
启用模板 haskell 推导,似乎任何具有 aeson
pre 2.1.1.0
的 aeson
都无法使用,我怀疑我们很多人都是这种情况。