F#:通过签名匹配函数

F#:通过签名匹配函数,f#,polymorphism,pattern-matching,f#-4.1,F#,Polymorphism,Pattern Matching,F# 4.1,我有一个关于通过签名匹配函数的问题。我问这个是为了学习,我知道有很多方法可以解决这个问题 假设在F#中,我有以下类似类型: type T1 = int * int * int type T2 = {a:int ; b:int; c:int} 而它们之间的转换就像 let convert p = match p with |(x,y,z) -> {a = x; b = y; c = z} 还假设我有一个为T1编写的大量函数库,现在我想与T2一起重用,例如: let add

我有一个关于通过签名匹配函数的问题。我问这个是为了学习,我知道有很多方法可以解决这个问题

假设在F#中,我有以下类似类型:

type T1 = int * int * int
type T2 = {a:int ; b:int; c:int}
而它们之间的转换就像

let convert p =
    match p with
    |(x,y,z) -> {a = x; b = y; c = z}
还假设我有一个为
T1
编写的大量函数库,现在我想与
T2
一起重用,例如:

let addT1 a b =
    match a, b with
    |(x1,y1,z1),(x2,y2,z2) -> (x1 + x2, y1 + y2, z1 + z2)

let negT1 = 
    function
    |(x,y,z) -> (-x,-y-z)

let offset a i =
    match a with
    |(x,y,z) -> (x + i, y + i, z + i)
如您所见,所有函数都依赖于
T1
,但可能会获得多个
T1
参数或其他类型的参数

我对此很熟悉,witch允许我将任何函数
(f:int*int*int->'a)
映射到函数
(g:T2->'a)

但在
addT1
的情况下,由于第二个参数,这不起作用:

val addT1 : int * int * int -> int * int * int -> int * int * int
val (funcOfT2 addt1) : (T2 -> int * int * int -> int * int * int)
所以,要使用像
funcOfT2
这样的函数,我必须这样使用它,这是不切实际的:

let p1 = {a = 1; b = 2; c = 3}
let p2 = {a = 2; b = 3; c = 4}
let x = funcOfT2 (funcOfT2 addT1 p1) p2
val x = int * int * int = (3,5,7)
我还可以为
T1
的每个函数制作一个本地版本,每次使用
T1
函数时传递必要数量的
funcOfT2
或使用
convert
,但我相信这确实是不切实际的,而且会造成代码混乱

是否存在匹配函数签名的方法,以便我可以将任何采用
T1
的函数转换为
T2
的函数

我的想法是这样的,因为很多原因它不起作用,但我认为它可能是我想要的例子。有什么办法吗

let rec myDream f =
    match f with
    |(g: T1 -> 'a) -> fun (t:T2) rest -> fOfT2 (g (convert t)) rest
    |(g: 'b -> 'c) -> fun x y -> fOfT2 (g x) y
    |(g: 'd) -> g d

转换参数不是比转换函数更容易吗?是的,出于实际目的。相反,我的目的是学习并了解是否有任何方法可以使用这种签名匹配进行泛型函数映射。如果这样的事情有可能的话,它会非常强大。这基本上意味着,如果我可以在两种类型之间转换,我可以使用其他类型的所有可用函数,而不必单独包装它们。我可以尝试找到一种使用静态约束的方法,但我向您保证,这将非常困难。只有非常高级的用户才能(经过一些心理训练)理解正在发生的事情。
let rec myDream f =
    match f with
    |(g: T1 -> 'a) -> fun (t:T2) rest -> fOfT2 (g (convert t)) rest
    |(g: 'b -> 'c) -> fun x y -> fOfT2 (g x) y
    |(g: 'd) -> g d