Haskell and Rust (and maybe other languages of which I am not aware) have a feature which they call "pattern matching". Here is an example in Haskell:
data Event = HoldKey Char | PressKey Char | Err String
someFunc = let
someEvent <- doSomeStuff
-- What follows is a case expression using pattern matching
thingINeed <- case someEvent of
HoldKey keySym -> process keySym
PressKey keySym -> process keySym
Err err -> exit err
in keepDoingStuff
The closest thing to this in Raku seems to be multi routines (both functions and methods).
class Hold { has $.key; }
class Press { has $.key; }
class Err { has $.msg; }
multi process(Hold (:$key)) { say $key; }
multi process(Press (:$key)) { say $key; }
multi process(Err (:$msg)) { say $msg; }
But this doesn't help if I want a "local" pattern matching expression (like the case
expression in the haskell snippet above). Something like this:
given Hold.new(:key<a>) {
when Hold (:$key) { say $key }
when Press (:$key) { say $key }
when Err (:$msg) { say $msg }
default { say "Unsupported" }
}
Which alas does not compile. So am I missing something or can Raku express this in some other way?
You are trying to use a Signature where no Signature is expected.
The Signature would more likely be part of the blocks, so it would look more like this:
given Hold.new(:key<a>) {
when Hold -> (:$key) { say $key }
when Press -> (:$key) { say $key }
when Err -> (:$msg) { say $msg }
default { say "Unsupported" }
}
That doesn't currently work as the blocks don't get any arguments.
It could be argued that this would be a useful feature to add.
Note that there is only two things that given
does.
proceed
and succeed
to finalize to.$_
to the value you are giving it.So that means that $_
is already set to the value you are smartmatching against.
given Hold.new(:key<a>) {
when Hold { say .key }
when Press { say .key }
when Err { say .msg }
default { say "Unsupported" }
}