sanctuary-js / sanctuary

:see_no_evil: Refuge from unsafe JavaScript
https://sanctuary.js.org
MIT License
3.03k stars 94 forks source link

regexp: simplify return types of S.match and S.matchAll #694

Closed davidchambers closed 3 years ago

davidchambers commented 3 years ago

match and matchAll are currently not enjoyable to use. I know why the return types are complex, but I still find accessing captured values annoying:

> S.join (S.chain (S.compose (S.head)
.                            (S.prop ('groups')))
.                 (S.match (/^(info|warn|error): (.*)$/i)
.                          ('info: Opening database connection...')))
Just ('info')

This pull request simplifies the match type, making captured values easier to access:

> S.join (S.chain (S.head)
.                 (S.match (/^(info|warn|error): (.*)$/i)
.                          ('info: Opening database connection...')))
Just ('info')

Before:

match :: NonGlobalRegExp -> String -> Maybe { match :: String, groups :: Array (Maybe String) }
matchAll :: GlobalRegExp -> String -> Array { match :: String, groups :: Array (Maybe String) }

After:

match :: NonGlobalRegExp -> String -> Maybe (Array (Maybe String))
matchAll :: GlobalRegExp -> String -> Array (Array (Maybe String))

Losing match :: String is not a problem in most cases, for the reason given in #686:

Unlike replace', S.replaceBy ignores the “match” argument provided by String#replace (when given a function). This simplifies the function's type, and saves one from using S.K (...) when only the captured groups are important (as is commonly the case). If one does require access to the matched substring as a whole, one can use /(...)/ to capture it. Admittedly, this approach is impractical if the RegExp object is defined in another module, but in such exceptional cases one can of course use String#replace directly.

Interestingly, the proposed type of match is the same as the function's type prior to #283. The incoherence @rjmk exposed in #253 does not apply, though, as the match is now omitted rather than prepended to the array of captured values.