Пытаясь разобрать рекурсивный JSON, я на правильном пути? - PullRequest
4 голосов
/ 18 октября 2011

Эта проблема связана с этим вопросом.

Вот тип данных, который я хочу сделать из JSON:

data ProdObject = MKSpair (Text, Text)
                | MKSLpair (Text, [Text])
                | MKSOpair (Text, ProdObject)
                | MKObject ProdObject
                | End
                deriving Show

Здесь - это образец данных, с которыми я работаю, плюс обобщениев целом.

Вот мое определение экземпляра, который вызывает ошибку.Я использовал этот в качестве ссылки.Я не уверен, что ошибка говорит мне, чтобы исправить мой тип, или что я далеко.Если ошибка действительно проста, я хотел бы получить несколько советов о том, как исправить мой тип, а также любые советы о том, что еще я могу делать неправильно, но пока не заметил.

instance FromJSON ProdObject where
  parseJSON (Object o) = MKObject <$> parseJSON o
  parseJSON (String s, String t)  = MKSpair (s, t)
  parseJSON (String s, Object o)  = MKSOpair (s, MKObject <$> parseJSON o)
  parseJSON (String s, Array a) = MKSLpair (s, V.toList a)
  parseJSON (Done d) = End
  parseJSON _        = mzero

Вотошибка, которую я имею прямо сейчас:

ghcifoo> :load test
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:23:52:
    Couldn't match expected type `Value'
                with actual type `Data.Map.Map Text Value'
    Expected type: Value
      Actual type: Object
    In the first argument of `parseJSON', namely `o'
    In the second argument of `(<$>)', namely `parseJSON o'
Failed, modules loaded: none.

Обновление: я переделал свой тип данных, если я прав, у меня есть фантомный тип.Если я не прав, вернемся к чертежной доске

data ProdObject = MKSpair (Text, Text)
                | MKSLpair (Text, [Text])
                | MKSOpair (Text, ProdObject)
                | MKObject ProdObject (k,v)
                | End

Также я отразил это изменение в моем случае, хотя и не полностью.Я упоминаю об этом просто, чтобы спросить, нахожусь ли я на правильном пути или нет.

parseJSON (Object (k,v)) = MKObject ...

Если я на правильном пути, я думаю, что могу либо выяснить остальное, или, по крайней мере, спросить конкретныйвопрос.Кто-нибудь отзыв?

1 Ответ

1 голос
/ 18 октября 2011

В этом уравнении:

parseJSON (Object o) = MKObject <$> parseJSON o

o имеет тип Map Text Value, но parseJSON имеет тип Value -> Parser a, поэтому вы, очевидно, не можете применить parseJSON к o.

Также у вас есть ошибка типа здесь:

parseJSON (String s, String t)  = MKSpair (s, t)

Тип parseJSON равен Value -> Parser a, но вы пытаетесь сопоставить его с (Value, Value).

То же самое относится к этой строке:

parseJSON (Done d) = End

Done не является конструктором типа Value.


Я не мог понять, почему вам нужен тип ProdObject для рекурсии; вот как бы я решил эту проблему:

data Outer = Outer {
  oName :: Text,
  oProducts :: M.Map Text Inner
} deriving Show

data Inner = Inner {
  iQA :: Text,
  iVM :: Text,
  iAvailable :: V.Vector Text
} deriving Show

instance FromJSON Outer where
    parseJSON (Object o) = Outer <$> o .: "name" <*> o .: "products"
    parseJSON _ = mzero

instance FromJSON Inner where
  parseJSON (Object o) = Inner <$> o .: "qa" <*> o .: "vm" <*> o .: "available"
  parseJSON _ = mzero

Полный список кодов можно найти на Github .

...