F # имеет функцию, позволяющую пользователям расширять сопоставление шаблонов:
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd
match 3 with | Odd -> printfn "odd"
| Even -> printfn "even"
или
(** Parsing date from any of the formats: MM/DD/YY, MM/DD/YYYY, YYYY-MM-DD *)
let parseDate = function
| ParseRegex "(\d{1,2})/(\d{1,2})/(\d{1,2})$" [Integer m; Integer d; Integer y]
-> new DateTime(y + 2000, m, d)
| ParseRegex "(\d{1,2})/(\d{1,2})/(\d{3,4})" [Integer m; Integer d; Integer y]
-> new DateTime(y, m, d)
| ParseRegex "(\d{1,4})-(\d{1,2})-(\d{1,2})" [Integer y; Integer m; Integer d]
-> new DateTime(y, m, d)
Магия происходит в шаблоне ParseRegex, который определяется как таковой:
(** Definition of the MatchRegex active pattern *)
let (|ParseRegex|_|) rgx s = match Regex(rgx).Match(s) with
| m when not m.Success -> None
| m -> Some(List.tail [for x in m.Groups->x.Value])
Теперь ParseRegex можно использовать повсюду, и вся его точка состоит в том, что разбор частей строк может быть выполнен очень кратким образом.
Есть ли у Scala аналогичная функция?
В С# этот уровень лаконичности кажется труднодоступным, но, может быть, какой-то хитроумный трюк, использующий неявное преобразование, может помочь?