I would like to write a Haskell function that's behavior is dependent upon regex pattern matching one of the arguments. In a language like C/Python/Perl, I would definitely just use a large if/else construct, but I don't really have that option. What is the most idiomatic Haskell way to handle this?
I've considered guards, but they don't work: No instance for (Data.String.IsString source0)
:
function arg
| arg =~ "pattern1" = dothis arg
| arg =~ "pattern2" = dothat arg
| otherwise = failwith arg
The pattern matching used in case constructs would be perfect, if it handled Regex.
function arg = case arg of
(pattern1 match) -> dothis match
(pattern2 match) -> dothat match
_ -> failwith arg
Your first example does work for me:
import Text.Regex.Posix
function :: String -> String
function arg
| arg =~ "pattern1" = "1"
| arg =~ "pattern2" = "2"
| otherwise = "3"
I think your IsString
error is due to the overloaded string literals extension. Try to disable that, or alternatively try to use explicit String
strings:
function :: String -> String
function arg
| arg =~ ("pattern1"::String) = "1"
| arg =~ ("pattern2"::String) = "2"
| otherwise = "3"
Too noisy? You can push the cruft to the last lines.
function2 :: String -> String
function2 arg
| arg =~ s"pattern1" = "1"
| arg =~ s"pattern2" = "2"
| otherwise = "3"
where s :: String -> String
s = id
Need subgroup matching?
function3 :: String -> String
function3 arg
| [_,x]:_ <- arg =~ s"pat(t*)ern1" = "matched group: " ++ x
-- ...
On function3 "patttern1"
, variable x
will be bound to "tt"
. On function3 "xyz"
, the test will fail and the next branch will be tried.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With