#f# #tuples #pattern-matching #decomposition
#f# #Кортежи #сопоставление с шаблоном #разложение
Вопрос:
Просто любопытно, почему я не могу этого сделать:
let myFn (data : obj) =
match data with
| :? (string * string) as (s1, s2) -> sprintf "(%s, %s)" s1 s2 |> Some
| :? (string * string * int) as (s1, s2, i) -> sprintf "(%s, %s, %d)" s1 s2 i |> Some
| _ -> None
Как так получилось?
Комментарии:
1. Это было бы неплохо. Жаль, что это не поддерживается.
2. Хотя это можно было бы предложить в github.com/fsharp/fslang-suggestions , Я думаю, что это плохая идея, так как это побудило бы людей писать подобный код. Этого кода следует избегать, поскольку он требует использования
obj
и сопоставления типов. F # следует использовать типобезопасным способом, а использованиеobj
и понижение значения отвлекает от этого.
Ответ №1:
См. Спецификацию F #, раздел 7.3 «Как шаблоны»
Шаблон as имеет вид pat as ident
Это означает, что вам нужно использовать идентификатор после as
:
let myFn (data : obj) =
match data with
| :? (string * string) as s1s2 -> let (s1, s2) = s1s2 in sprintf "(%s, %s)" s1 s2 |> Some
| :? (string * string * int) as s1s2i -> let (s1, s2, i) = s1s2i in sprintf "(%s, %s, %i)" s1 s2 i |> Some
| _ -> None
Комментарии:
1. Я знаю, что говорится в спецификации. Я искал более техническое объяснение того, почему деконструкция кортежа после «as» не поддерживается, тем более, что большинство пользователей интуитивно понимают этот язык.
2. Технических ограничений нет, кроме того, что функция не реализована. Есть и другие места, где деконструкция не поддерживается, например, в параметре «this» членов, который является местом, где вы часто хотите деконструировать. Все это можно добавить в язык после отправки предложения и получения его одобрения.