Aeson: разобрать объект json в списке - PullRequest
0 голосов
/ 26 ноября 2018

Я хотел бы проанализировать значения объекта json в списке.

Вот мой текущий подход (упрощенный, и новый тип основан на результатах: Aeson: получить некоторые (но невсе) поля структуры (значит, мне это нужно)):

Json:

{"v1": 1, "v2": 2}

Требуемый результат:

Test [1,2]

Текущий подход:

import Data.Aeson
import Data.HashMap.Strict (elems)

newtype Test = Test [Int]
instance FromJSON Test where
  parseJSON (Object o) =
    mapM parseJSON (elems o)

Ошибка компиляции:

• Couldn't match type ‘[b0]’ with ‘Test’
  Expected type: aeson-1.1.2.0:Data.Aeson.Types.Internal.Parser Test
    Actual type: aeson-1.1.2.0:Data.Aeson.Types.Internal.Parser [b0]
• In the expression: mapM parseJSON (elems o)

1 Ответ

0 голосов
/ 26 ноября 2018

mapM parseJSON (elems o) возвращает Parser [Int], но вам нужно Parser (Test [Int]), поэтому правильный способ сделать это:

instance FromJSON Test where
    parseJSON (Object o) = Test <$> mapM parseJSON (elems o)

Однако тип аргумента parseJSON равен Valueзначение аргумента не может быть Object, оно также может быть Array, String или т. д., поэтому лучше использовать withObject, чтобы проверить, что это такое:

instance FromJSON Test where
    parseJSON val = withObject "Test" 
                               (\o -> Test <$> mapM parseJSON (elems o))
                               val

withObject выведет значимое сообщение об ошибке, если значение типа Value не равно Object.

...