In the Str module, replaceEach, replaceFirst, replaceLast, splitFirst, and splitLast each return a Result with NotFound as the error tag. These are certainly more convenient than doing equality checks in code that needs to know if a change occurred (and presumably these permit better optimizations than such checks).
However, there are also, perhaps more commonly, cases where the programmer simply does not care if the change occurred (i.e. optimistic string sanitation). In such cases, it would be convenient if unchecked variants existed which returned the original string whenever no match is found.
In the case of the splitFirst and splitLast functions, the unchecked variants could have the after and before fields, respectively, as empty strings in the case where a match was not found.
For what it's worth, you can implement this today with |> Result.withDefault myOriginalString.
Indeed! I brought up ^^ because I've done this a notable number of times while working on Advent of Code puzzles, as well as creating helpers based on your suggestion that could well have been in the stdlib.
There's certainly a trade-off here to consider carefully for the language: do we make Roc more of a "batteries included" language (at least for non-platform concepts) at the expense of making more documentation to dig through for experienced programmers, or do we provide basics at the expense of requiring more programmer knowledge before they're capable of solving common tasks?
My general preference goes to batteries included, for documentation we should have good search functionality.
so I guess the idea would be to have e.g. replaceFirst and replaceFirstChecked? If so, that sounds reasonable to me!
Last updated: Jun 16 2026 at 16:19 UTC