haskell / haskell/aeson

Propoal: operators similar to .= for Maybe or Functor/Applicative types

Open
#516 4 comments 1 reaction 0 assignees View on GitHub
help wanted
Dominant language
Haskell
Stars
1.3k
Forks
336
Avg merge
3d 7h
Merged PRs (30d)
4

Description

Oftentimes when manually writing `ToJSON` instances, we have fields with `Maybe` types and we want to just hide the field if its value is `Nothing`. I usually resort to something like this:

```haskell
data A =
A
{ x :: Int
, y :: Maybe Int
}

instance ToJSON A where
toJSON (A x y) =
object $ catMaybes
[ Just ("x" .= x)
, ("y" .=) <$> y
]
```

In my opinion, that is not very elegant. I propose adding the following two operators to make this nicer:

```haskell
(.=!) :: (Applicative f, ToJSON v, KeyValue kv) => Text -> v -> f kv
k .=! v = pure $ k .= v
(.=?) :: (Functor f, ToJSON v, KeyValue kv) => Text -> f v -> f kv
k .=? v = (k .=) <$> v
````

I envision these operators becoming the duals of `.:!` and `.:?`, which are very useful when parsing. Using them would look like this:

```haskell
instance ToJSON A where
toJSON (A x y) =
object $ catMaybes
[ "x" .=! x
, "y" .=? y
]
```

I'm still undecided if the general `Functor`/`Applicative` constraints are that useful, or if we should just specialize these operators to `Maybe`:

```haskell
(.=!) :: (ToJSON v, KeyValue kv) => Text -> v -> Maybe kv
k .=! v = Just $ k .= v
(.=?) :: (ToJSON v, KeyValue kv) => Text -> Maybe v -> Maybe kv
k .=? v = (k .=) <$> v
```

Let me know what you think. I'm still a little hesitant on this proposal, mainly because I want to avoid needless operator soup. I thought it was a decent idea though, so I decided to make open this issue to at least open up discussion.

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.