2015-01-24 11 views
5

Powiedzmy mam typ Personajzon i obiektywu z DeriveGeneric i makeLenses - nazwy nie kolejce

import GHC.Generics 
import Data.Text 
import Data.Aeson 
import Control.Lens 

data Person = Person { 
    _firstName :: Text, 
    _lastName :: Text, 
    _age  :: Int 
} deriving (Show, Generic) 

I chcę automatycznie czerpać Obiektywy i typeclasses JSON za nim

makeLenses ''Person 
instance FromJSON Person 
instance ToJSON Person 

Działa to poprawnie, jednak DeriveGeneric widzi moje nazwy pól jako mające podkreślenie i oczekuje, że mój JSON zostanie odpowiednio sformatowany.

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

Oczywiście mogę usunąć podkreślenia z samej definicji data, ale potem makeLenses nie będzie w stanie czerpać wymaganych pobierające i ustawiające.

Idealnie co chcę, aby być w stanie zrobić, to coś takiego

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

tj Chcę, aby móc czerpać soczewki i instancje JSON ze wszystkie nazwy pól w kolejce prawidłowo z wartościami w JSON- REST Api pochłaniam, bez konieczności pisania wielu szablonów.

Wydaje się to być tak proste, że czuję, że brakuje mi czegoś oczywistego?

Odpowiedz

8

Zarówno lens, jak i aeson mają funkcje pozwalające na konfigurowalną obsługę nazw pól i konstruktorów. Ponieważ domyślnym aeson „s nie jest to, co chcesz, i nie będzie działać w każdym razie jeśli chcesz nazwy soczewek być takie same jak nazwy pól JSON, zmieńmy konfigurację 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} 
-} 

Dla lens The odpowiednia funkcja konfigurowalna to makeLensesWith.

+0

Działa idealnie, dzięki :) –

Powiązane problemy