haskell/aeson

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

Open

#516 aberto em 3 de mar. de 2017

Ver no GitHub
 (4 comments) (1 reaction) (0 assignees)Haskell (334 forks)batch import
help wanted

Métricas do repositório

Stars
 (1.298 stars)
Métricas de merge de PR
 (Mesclagem média 89d 5h) (9 fundiu PRs em 30d)

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:

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:

(.=!) :: (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:

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:

(.=!) :: (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.

Guia do colaborador