How to write a lens-based function incrementing numerical suffix (if it exists) and keeping the string as is if no such one?
"aaa1" -> "aaa2"
"aaa_123" -> "aaa_124"
"" -> ""
"aaa" -> "aaa"
"123a" -> "123a"
"3a5" -> "3a6"
I have feeling that I need some prism maybe, first, but no idea which one (suffixed does not get a function as an argument but a scalar).
One quick way to figure out which kind of optic you need is considering the properties it should have. In your case, we can ask the questions suggested by this answer of mine, and note that:
Like a prism, your optic can fail, as there might not be a numeric suffix.
Unlike a prism, however, your optic is not reversible.
suffixedis reversible because its target is the prefix, and the suffix being matched is fixed. In your case, the target is the suffix, and the prefix can't be known in advance.The lack of reversibility suggests you want a traversal, rather than a prism. With the lens library, implementing a traversal is a matter of writing a function which fits the
Traversaltype:Here is one way of doing it for your purposes:
Notes on the implementation:
spanEndcomes from the extra package.Round-tripping through
ReadandShowas done here will strip leading zeroes from the prefix. If that's undesirable (which seems rather likely), you'll need something more refined thanshowto format the modified suffix.If the aforementioned round-tripping is not a problem, though, the implementation can be made very compact by using the
_Showprism as a traversal:Incrementing the suffix can then be straightforwardly done through
over: