lens / lens-aeson

Traversals and Prisms for Data.Aeson
MIT License
51 stars 18 forks source link

Add a 'keys' function, or maybe 'path' #5

Open jfischoff opened 10 years ago

jfischoff commented 10 years ago

Instead of writing

livingOnTheEdge = foo ^?! key "this" . key "is" . key "annoying"

I can write

keys = foldl' (\x f -> f . key x) id

livingOnTheEdge = foo ^?! keys ["this", "is","less", "annoying"]

Seems common enough to have in the library

bitemyapp commented 10 years ago

This project is deprecated and has been moved into Lens 4.

@jfischoff if this feature isn't in the Lens 4 version, could you refile this issue there?

glguy commented 10 years ago

Project is back in this repository, let's reopen the discussion about this being a good idea or not and then implement it or close the issue :)

rampion commented 7 years ago

If you want to be less verbose, why not

data X (f :: * -> *) = X {getX :: forall t. AsValue t => (Value -> f Value) -> t -> f t}

keys :: (AsValue t, Applicative f) => T.Text -> (Value -> f Value) -> t -> f t
keys = getX . L.foldr1 (\(X a) (X b) -> X (a . b)) . map (\k -> X $ key k) . T.splitOn "."

So now you do

λ "{ \"a\": { \"b\": { \"c\": 3 } } }" ^? keys "a.b.c"
Just (Number 3.0)
sjshuck commented 2 years ago

I think if key "foo" . key "bar" . key "baz" were ever deemed insufficient, the next step up should be something more substantial than to splitOn "." Perhaps incorporating https://hackage.haskell.org/package/jsonpath. lens-aeson could have a function doing [JSONPathElement] -> Traversal' Value Value, maybe a cool quasi-quoter validating syntax during compilation.

Although it may be more suitable as its own library, or incorporated into jsonpath using traversals-in-disguise or microlens.

EDIT: This exists: https://hackage.haskell.org/package/aeson-picker