F#:通过签名匹配函数

时间:2018-03-08 21:39:51

标签: 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 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的多个参数或其他类型的参数。

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

let funcOfT2 f = fun (t:T2) -> f (t.a, t.b, t.c)

但是在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函数时,我也可以使funcOfT2的每个函数的本地版本传递必要数量的convert或使用T1,但是我相信这将是不切实际的,并且会产生混乱的代码。

是否存在匹配函数签名的问题,以便我可以将任何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

0 个答案:

没有答案