I have a JSON blob similar to the following:
[
{
"version": 1
},
{
"version": "3"
},
...
]
Note that some of the versions are numbers and some are strings. I want to get a list of versions. I can use the following lens combination to extract the numeric versions:
v1 :: [String]
v1 = obj ^.. AL.values . AL.key fieldName . AL._Number . to show
And the following to extract the strings
v2 :: [String]
v2 = obj ^.. AL.values . AL.key fieldName . AL._String . to T.unpack
But, how can I get a list of versions by a single pass over the list?
Is there any lens combinator that takes lenses AL._Number . to show
and AL._String . to T.unpack
and returns a combined getter so that if the first one failes, tries the second one? Something like msum
for lenses?
There is in fact a combinator that tries an optic and goes to a backup if the first one fails. It's called failing.
Note that the condition on it should be satisfied by the case you describe. Even if it wasn't, the combinator would still function, it would just behave irregularly when refactoring. (Which is the main problem with using filtered as a Traversal
.)