Aeson and lens with DeriveGeneric and makeLenses - names do not line up

Say I have type 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) 

And I want to automatically output lenses and JSON types for it for

 makeLenses ''Person instance FromJSON Person instance ToJSON Person 

This works correctly, however DeriveGeneric sees that my field names have an underscore and expects my JSON to be formatted accordingly.

 { "_firstName": "James" ... etc} -- The underscore doesn't belong here. 

Obviously, I could remove the underline from the data definition itself, but then makeLenses could not get the necessary getters and setters.

Ideally, what I want to do is something like this

 let person = decode blob let name = person ^. firstName 

i.e. I want to get lenses and JSON instances with all field names that correctly match the values ​​in the Api JSON-REST that I consume, without having to write a lot of templates.

It seems like such a direct thing that I feel like I'm missing something obvious?

+5
source share
1 answer

Both lens and aeson have functions that allow you to customize the processing of field and constructor names. Since aeson is not what you want by default, and will not work if you want the lens names to be the same as the JSON field names, change the aeson configuration:

 {-# 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} -} 

For lens corresponding configurable function would be makeLensesWith .

+8
source

Source: https://habr.com/ru/post/1211813/


All Articles