您的代码不起作用,因为 F# 将参数类型概括为类型参数。我认为你不能动态测试类型是否'a * 'b
可以转换为类型MyType1 * MyType2
(尽管这对我来说有点令人困惑)。在任何情况下,您都可以编写一个带有两个类型参数的函数obj
并使用两个分别测试它们:?
图案:
type MyType1 = A | B of float
type MyType2 = C | D of int
let func (x:obj) (y:obj) =
match (x, y) with
| (:? MyType1 as x1), (:? MyType1 as x2) ->
printfn "%A %A" x1 x2
| _ ->
printfn "something else"
func A (B 3.0) // A B 3.0
func A (D 42) // something else
不管怎样,知道你为什么要这样做会很有趣?可能有更好的解决方案...
EDIT (2)因此,从所有 4 个二元素组合T1
and T2
,您想要可以接受 3 的函数。这是正确的吗(T1 * T1
, T1 * T2
and T2 * T2
)?在这种情况下,您无法编写完全安全的柯里化函数,因为第二个参数的类型将“依赖于”第一个参数的类型(如果第一个参数的类型为T2
,那么第二个参数也必须是T2
(否则可以是T1
too)).
您可以编写一个安全的非柯里化函数,该函数采用以下类型的参数:
type MyArg = Comb1 of T1 * T1 | Comb2 of T1 * T2 | Comb3 of T2 * T2
函数的类型是MyArg -> string
。
如果你想要一个柯里化函数,你可以定义一个类型,允许你使用T1
or T2
作为第一个和第二个参数。
type MyArg = First of T1 | Second of T2
然后,你的柯里化函数将是MyArg -> MyArg -> string
。但请注意,如果不允许使用一种参数类型组合(如果我理解正确的话,T2 * T1
不应该被允许)。在这种情况下,您的函数只需抛出异常或类似的东西。