Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically deriving instance for custom data type with Aeson/JSON

If I have a custom data type for parsing JSON with Aeson

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}]}"

giving:

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

How do I derive the instances for FromJSON automatically?

I have tried:

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

as has been suggested from some tutorials, but that gives:

λ> :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.

what am I doing wrong?

like image 935
matt Avatar asked Apr 26 '26 01:04

matt


1 Answers

What the error is telling you is that you have to enable the DeriveGeneric extension in order for this to work. So you have to add:

{-# LANGUAGE DeriveGeneric #-}

right at the top of your file, or compile using the -XDeriveGeneric flag.

like image 54
Bakuriu Avatar answered Apr 27 '26 15:04

Bakuriu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!