Saturday, April 30, 2022

[ljxgdqve] makeRegexOpts example

we demonstrate how to use the functions makeRegex and makeRegexOpts using the regex-tdfa Haskell regular expression package.

the key point is, you cannot use =~ if you want to use these functions.  if you do, for example:

bad :: String -> Bool;
bad s = s =~ (makeRegex "[[:digit:]]");

you will get inscrutable error messages:

* Ambiguous type variable `source0' arising from a use of `=~' prevents the constraint `(RegexMaker Regex CompOption ExecOption source0)' from being solved.

* Ambiguous type variables `source0', `compOpt0', `execOpt0' arising from a use of `makeRegex' prevents the constraint `(RegexMaker source0 compOpt0 execOpt0 [Char])' from being solved.

instead, you have to use matchTest or similar functions described in Text.Regex.Base.RegexLike in regex-base.  the functions are reexported by but not documented in Text.Regex.TDFA .

https://gabebw.com/blog/2015/10/11/regular-expressions-in-haskell is a good explanation.

below is an example program that searches case-insensitively for input lines that contain the substring "gold", equivalent to "grep -i gold".  we need to use makeRegexOpts to disable case sensitivity.

module Main where {
import qualified Text.Regex.TDFA as Regex;

main :: IO();
main = getContents >>= ( mapM_ putStrLn . filter myregex . lines);

myregex :: String -> Bool;
myregex s = Regex.matchTest r s where {
  r :: Regex.Regex;
  r = Regex.makeRegexOpts mycompoptions myexecoptions "gold" ;
  mycompoptions :: Regex.CompOption;
  mycompoptions = Regex.defaultCompOpt {Regex.caseSensitive = False}; -- record syntax
  myexecoptions :: Regex.ExecOption;
  myexecoptions = Regex.defaultExecOpt;
};
}

here is documentation about all the available ExecOption and CompOption for this TDFA regex implementation.

previously, on the lack of substitution in Haskell regexes.

No comments :