haskell/aeson

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

Open

#516 建立於 2017年3月3日

在 GitHub 查看
 (4 留言) (1 反應) (0 負責人)Haskell (1,298 star) (334 fork)batch import
help wanted

描述

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.

貢獻者指南