Aeson 和 Lens with DeriveGeneric 和 makeLenses - 名称不一致
Aeson and Lens with DeriveGeneric and makeLenses - names don't line up
假设我有一个类型 Person
import GHC.Generics
import Data.Text
import Data.Aeson
import Control.Lens
data Person = Person {
_firstName :: Text,
_lastName :: Text,
_age :: Int
} deriving (Show, Generic)
我想为它自动派生 Lenses 和 JSON 类型类
makeLenses ''Person
instance FromJSON Person
instance ToJSON Person
这可以正常工作,但是 DeriveGeneric 认为我的字段名称带有下划线,并希望我的 JSON 被相应地格式化。
{ "_firstName": "James" ... etc} -- The underscore doesn't belong here.
显然我可以从 data
定义本身中删除下划线,但是 makeLenses
将无法派生所需的 getter 和 setter。
理想情况下,我希望能够做的是这样的事情
let person = decode blob
let name = person ^. firstName
即我希望能够派生镜头和 JSON 实例,所有字段名称都与我正在使用的 JSON-REST Api 中的值正确对齐,而无需编写太多样板.
这似乎是一件很直接的事情,我觉得我错过了一些明显的东西?
lens
和 aeson
都具有允许自定义处理字段和构造函数名称的函数。由于 aeson
的默认值不是您想要的,如果您希望镜头名称与 JSON 字段名称相同,则无论如何都行不通,让我们更改 aeson
配置:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
import GHC.Generics
import Data.Text hiding (drop)
import Data.Aeson
import Data.Aeson.TH
import Data.Aeson.Types
import Control.Lens
data Person = Person {
_firstName :: Text,
_lastName :: Text,
_age :: Int
} deriving (Show, Generic)
makeLenses ''Person
deriveJSON defaultOptions{fieldLabelModifier = drop 1} ''Person
{- alternative Generic version
instance FromJSON Person where
parseJSON = genericParseJSON defaultOptions{fieldLabelModifier = drop 1}
instance ToJSON Person where
toJSON = genericToJSON defaultOptions{fieldLabelModifier = drop 1}
-}
对于lens
,对应的可配置函数为makeLensesWith
。
假设我有一个类型 Person
import GHC.Generics
import Data.Text
import Data.Aeson
import Control.Lens
data Person = Person {
_firstName :: Text,
_lastName :: Text,
_age :: Int
} deriving (Show, Generic)
我想为它自动派生 Lenses 和 JSON 类型类
makeLenses ''Person
instance FromJSON Person
instance ToJSON Person
这可以正常工作,但是 DeriveGeneric 认为我的字段名称带有下划线,并希望我的 JSON 被相应地格式化。
{ "_firstName": "James" ... etc} -- The underscore doesn't belong here.
显然我可以从 data
定义本身中删除下划线,但是 makeLenses
将无法派生所需的 getter 和 setter。
理想情况下,我希望能够做的是这样的事情
let person = decode blob
let name = person ^. firstName
即我希望能够派生镜头和 JSON 实例,所有字段名称都与我正在使用的 JSON-REST Api 中的值正确对齐,而无需编写太多样板.
这似乎是一件很直接的事情,我觉得我错过了一些明显的东西?
lens
和 aeson
都具有允许自定义处理字段和构造函数名称的函数。由于 aeson
的默认值不是您想要的,如果您希望镜头名称与 JSON 字段名称相同,则无论如何都行不通,让我们更改 aeson
配置:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TemplateHaskell #-}
import GHC.Generics
import Data.Text hiding (drop)
import Data.Aeson
import Data.Aeson.TH
import Data.Aeson.Types
import Control.Lens
data Person = Person {
_firstName :: Text,
_lastName :: Text,
_age :: Int
} deriving (Show, Generic)
makeLenses ''Person
deriveJSON defaultOptions{fieldLabelModifier = drop 1} ''Person
{- alternative Generic version
instance FromJSON Person where
parseJSON = genericParseJSON defaultOptions{fieldLabelModifier = drop 1}
instance ToJSON Person where
toJSON = genericToJSON defaultOptions{fieldLabelModifier = drop 1}
-}
对于lens
,对应的可配置函数为makeLensesWith
。