Сопоставление тестового шаблона типа 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

Почему?


person MiloDC    schedule 09.11.2020    source источник
comment
Это было бы чудесно. Жалко, что не поддерживается.   -  person TheQuickBrownFox    schedule 09.11.2020
comment
Хотя это можно было бы предложить в github.com/fsharp/fslang-suggestions , я думаю, что это плохая идея, так как это побудит людей писать такой код. Этого кода следует избегать, поскольку он требует использования obj и сопоставления типов. F# следует использовать безопасным для типов способом, а использование obj и приведения вниз отвлекает от этого.   -  person Charles Roddie    schedule 16.11.2020


Ответы (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
person Gus    schedule 09.11.2020
comment
Я знаю, что написано в спецификации. Я искал более техническое объяснение того, почему деконструкция кортежа после as не поддерживается, тем более что большинство пользователей интуитивно понимают это в языке. - person MiloDC; 10.11.2020
comment
Технических ограничений нет, кроме того, что эта функция не реализована. Есть и другие места, где деконструкция не поддерживается, например, в этом параметре элементов, где вы часто хотите деконструировать. Все это можно добавить в язык после подачи предложения и получения на него одобрения. - person Gus; 10.11.2020