Чтобы избежать переноса нового типа из очень хороший ответ Пола Джонсона по всей кодовой базе, вы также можете обобщить свой тип следующим образом, сделав тип myobject
параметром:
data MyStruct_ intList = MyStruct {
myobject :: intlist,
...
} deriving (Functor, Generic)
type MyStruct = MyStruct [Int]
instance FromJSON MyStruct where
parseJSON = (fmap . fmap) (\(MySpecialType i) -> i)
. genericParseJSON defaultOptions
genericParseJSON
выше получает экземпляр с MyStruct MySpecialType
, а затем поле разворачивается через fmap
(отмечая MyStruct_
это Functor
)
Я также только что написал blogpost о «типовой хирургии» , примененный к такого рода проблеме, чтобы вы могли сохранить исходный тип неизмененным.
Библиотека операций с общими данными может получитьуниверсальный тип с той же структурой Generic
, что и MyStruct_ MySpecialType
выше, для использования в genericParseJSON
aeson.Затем операция modifyRField
применяет функцию \(MySpecialType i) -> i
к полю myobject
, в результате чего получается MyStruct
.
import Generic.Data.Surgery (fromOR, toOR', modifyRField)
-- The original type
data MyStruct = MyStruct {
myobject :: [Int],
...
} deriving (Generic)
instance FromJSON MyStruct where
parseJSON = fmap (fromOR . modifyRField @"myobject" (\(MySpecialType i) -> i) . toOR')
. genericParseJSON defaultOptions
.