Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aeson's deriveJSON doesn't work as expected for enums

Tags:

haskell

aeson

I usually write my own ToJSON and FromJSON instances, but I decided to use deriveJSON for a type because it was so simple:

data Priority = HIGH | MEDIUM | LOW deriving Show
$(deriveToJSON id ''Priority)

main = BS.putStrLn . encode $ HIGH

I would've expected the JSON derivation to just write out the enum as a string. Instead, it's the key to a hash! {"HIGH":[]}

Why is this the default behavior?

like image 306
Vlad the Impala Avatar asked Sep 06 '25 03:09

Vlad the Impala


1 Answers

It's because aeson doesn't distinguish between sum types like your Priority and more sophisticated types like data PriorityAndDetails = HIGH { highReason :: Text, alertType :: Alert } | MEDIUM { personResponsible :: Person } | LOW. Fundamentally each of these types are "just a data constructor with n arguments".

In Priority HIGH, MED, and LOW are each just data constructors with zero arguments. In PriorityAndDetails HIGH, MED, and LOW are each just data constructors with some number of named arguments, 2, 1, and 0 respectively.

Generally I've found that you're likely to need to create your own ToJSON and FromJSON instances for anything besides early prototyping.

like image 93
J. Abrahamson Avatar answered Sep 09 '25 18:09

J. Abrahamson