2016-02-29 9 views
1

Если у меня есть тип данных для разбора JSON с эсонАвтоматически получение экземпляра для пользовательского типа данных с эсонами/JSON

data Response = Response 
    { response :: [Body] 
    } deriving (Show) 

instance FromJSON Response where 
    parseJSON (Object v) = Response <$> v .: "response" 
    parseJSON _ = mzero 

data Body = Body 
    { body_id    :: Int 
    , brandId    :: Int 
    } deriving (Show) 

instance FromJSON Body where 
    parseJSON (Object v) = Body 
     <$> v .: "id" 
     <*> v .: "brandId" 
    parseJSON _ = mzero 

raw :: BS.ByteString 
raw = "{\"response\":[{\"id\":5977,\"brandId\":87}]}" 

дает:

λ> decode raw :: Maybe Response 
Just (Response {response = [Body {body_id = 5977, brandId = 87}]}) 

Как получить экземпляры для FromJSON автоматически?

Я попытался:

data Response = Response 
    { response :: [Body] 
    } deriving (Show,Generic) 

data Body = Body 
    { body_id    :: Int 
    , brandId    :: Int 
    } deriving (Show,Generic) 

instance FromJSON Response 
instance FromJSON Body 

как было предложено из некоторых учебников, но это дает:

λ> :l response.hs 
[1 of 1] Compiling Response   (response.hs, interpreted) 

response.hs:19:22: 
    Can't make a derived instance of `Generic Response': 
     You need DeriveGeneric to derive an instance for this class 
    In the data declaration for `Response' 

response.hs:24:22: 
    Can't make a derived instance of `Generic Body': 
     You need DeriveGeneric to derive an instance for this class 
    In the data declaration for `Body' 
Failed, modules loaded: none. 

, что я делаю неправильно?

ответ

11

Что означает ошибка, так это то, что вы должны включить расширение DeriveGeneric, чтобы это работало. Таким образом, вы должны добавить:

{-# LANGUAGE DeriveGeneriC#-} 

права в верхней части файла, или скомпилировать с помощью -XDeriveGeneric флага.

+0

Спасибо! который зафиксировал это. а также спасибо за редактирование моего сообщения. – matthias

+1

еще одна вещь. Вы заметите «id» в 'raw =" {\ "response \": [{\ "id \": 5977, \ "brandId \": 87}]} "'; можно ли перезаписать часть автоматически производного экземпляра? id явно зарезервирован, и у JSON, который получен, есть «id» в нем, и я бы предпочел не использовать идентификатор в моем типе данных. – matthias

+0

@matthias Я сомневаюсь, что вы можете это сделать. Но я не эксперт по эзону. Вы можете попытаться открыть новый вопрос об этой проблеме. – Bakuriu