lens / lens-aeson

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

Astonishing 'values' behaviour - reducing to a single value #32

Closed alaendle closed 4 years ago

alaendle commented 4 years ago

Not sure if this is correct behaviour that I just don't understand or if this is a bug.

("{\"a\": [ { \"b\": [ 1, 2, 3]}] }" :: Text) ^? key "a" . nth 0 . key "b" . values

returns

Just (Number 1.0)

What looks weird to me because if I remove the . values I get:

("{\"a\": [ { \"b\": [ 1, 2, 3]}] }" :: Text) ^? key "a" . nth 0 . key "b" 
Just (Array [Number 1.0,Number 2.0,Number 3.0])

Thanks in advance for any assistance.

Taneb commented 4 years ago

This is expected, if a little non-obvious, behaviour.

The type of key "a" . nth 0 . key "b" . values is AsValue t => IndexedTraversal Int t Value which here, used as the argument to (^?), acts as Fold Text Value. (^?) returns the first, if any, element of a fold, so here, the first element of that inner list. This is why you see Just (Number 1.0) and when you drop the use of values you get the the whole array.

If you want to return a list, you can use (^..) in place of (^?), which returns every element of a a fold.

alaendle commented 4 years ago

Many thanks @Taneb - with your explanation it really gets obvious! But believe me I stared at these code snippets for hours before I've created this issue. Maybe something that every haskell/lens beginner has to go through 😅