我有一些这样的实用函数,它们返回不同长度的元组:
let get1And2Of4(v1, v2, v3, v4) = v1, v2
let get1And2And3Of4(v1, v2, v3, v4) = v1, v2, v3
我希望能够对变量进行模式匹配并返回适当的实用程序函数。
例如,
let bar =
match foo with
| "A" -> get1And2Of4
| "B" -> get1And2And3Of4
但是,编译器会抱怨,因为元组的长度不同。读取Variable length tuples in f#和Elegant pattern matching on nested tuples of arbitrary length解释这实际上是不可能的。
鉴于我需要使用元组而不是列表,是否还有其他选择可以实现此目的?
我可以想象的唯一可行的,类型安全的方法是将其全部清楚地拼出,然后将这些函数作为个别情况包装在一个有区别的联合中。这显然很尴尬;从正面来看,它可以帮助您跟踪所涉及的各种类型参数,因为最终所有代码路径都需要返回相同的类型。
type WhateverYouFeelNamingTheDU<'a,'b,'c,'d> =
| Get1And2Of4 of ('a * 'b * 'c * 'd -> 'a * 'b)
| Get1And2And3Of4 of ('a * 'b * 'c * 'd -> 'a * 'b * 'c)
let get1And2Of4 = Get1And2Of4(fun (v1, v2, v3, _) -> v1, v2)
let get1And2And3Of4 = Get1And2And3Of4(fun (v1, v2, v3, _) -> v1, v2, v3)
match "foo" with
| "A" -> get1And2Of4
| _ -> get1And2And3Of4
|> function
| Get1And2Of4 f42 -> f42 (1,2,"a","b") |> string
| Get1And2And3Of4 f43 -> f43 (3,4,"c","d") |> string
// val it : string = "(3, 4, c)"