【问题标题】:F# type test pattern matching: decomposing tuple objectsF#类型测试模式匹配:分解元组对象
【发布时间】:2021-02-21 02:57:20
【问题描述】:

只是好奇为什么我不能这样做:

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

怎么会?

【问题讨论】:

  • 那太好了。可惜不支持。
  • 虽然这可以在 github.com/fsharp/fslang-suggestions 中提出建议,但我认为这是一个坏主意,因为它会鼓励人们编写这样的代码。应避免使用此代码,因为它需要使用 obj 和类型匹配。 F# 应该以类型安全的方式使用,而使用 obj 和向下转换会减损这一点。

标签: f# tuples pattern-matching decomposition


【解决方案1】:

参见F# spec,第 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

【讨论】:

  • 我知道规范是怎么说的。我正在寻找一个更技术性的解释,说明为什么不支持在“as”之后解构元组——尤其是因为大多数用户都会凭直觉理解这种语言。
  • 没有技术限制,只是没有实现该功能。还有一些不支持解构的地方,比如members的“this”参数,就是经常要解构的地方。所有这些都可以在提交提案并获得批准后添加到语言中。
猜你喜欢
  • 2023-01-08
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多