haskell / haskell/aeson

Unexpected behaviour with Maybe typed fields and UntaggedValue

Open
#720 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
1.3k
Forks
336
Avg merge
3d 7h
Merged PRs (30d)
4

Description

I'm not sure if this is a bug or a feature so I thought I'd check. Here is a minimal working example.

```haskell
{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
import Data.Aeson
import Data.Aeson.TH

data Fruit = Apple { a :: Integer, b :: Maybe Bool }
| Banana { a :: Integer }
deriving Show
$(deriveJSON defaultOptions { sumEncoding = UntaggedValue } 'Apple)

main :: IO ()
main =
do
putStrLn $ show (decode "{ \"a\": 10 }" :: Maybe Fruit)
-- Expected Just (Banana {a = 10}), got Just (Apple {a = 10, b = Nothing})
putStrLn $ show (decode "{ \"a\": 10, \"b\": true }" :: Maybe Fruit)
-- Should be and got Just (Apple {a = 10, b = Just True})

```

Since the `omitNothingFields` is `False` by default, and when it is false `Nothing`s are encoded as `null` (rather than omitted). I'd expect `{ "a": 10 }` to decode as a `Banana`.

Likewise when `omitNothingFields` is false I'd expect to get `Nothing` for the following example.

```haskell
{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
import Data.Aeson
import Data.Aeson.TH

data Fruit = Apple { a :: Integer, b :: Maybe Bool }
deriving Show
$(deriveJSON defaultOptions 'Apple)

main :: IO ()
main =
do
putStrLn $ show (decode "{ \"a\": 10 }" :: Maybe Fruit) -- Expected Nothing, got (Apple { a = 10, b = Nothing})
```
I expect this is a design choice rather than a bug, If this is the case perhaps it could be documented more clearly or highlighted in the documentation for `UntaggedValue` e.g.

> Note: Since omitted `Maybe` typed fields decode to `Nothing`, the set of non-maybe fields from each constructor should be disjoint.

If this is indeed a bug, I have hacked together a [patch](https://gist.github.com/edwardb96/aa9cefde626a5141b2cf28ce3c1a7962) for my own purposes but would be happy to tidy it up and turn it into a PR.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.