F#:奇怪的类型推断行为

时间:2009-07-30 17:13:48

标签: f# types

首先,我有一个更好的方法来处理这个问题所以这不是问题。

然而,这是我不明白的事情。有人可以解释一下吗?

当我将交换功能定义为:

namespace Utilities
module Misc

let Swap (left : 'a byref) (right : 'a byref) =
    let temp = left
    left  <- right
    right <- temp

我能够像这样使用Swap函数。

Misc.Swap (&s.[i]) (&s.[j])

但是当我定义模块时:

namespace Utilities

type Misc =
    static member Swap (left : 'a byref) (right : 'a byref) =
        let temp = left
        left  <- right
        right <- temp

我在两个参数上都收到以下错误:

This expression has type  'b byref but is here used with type  'a ref

如何通过将函数移动到类型来改变调用者参数的类型推断?

1 个答案:

答案 0 :(得分:2)

这可能是F#编译器对类方法执行的元组转换的交互。

Reflector将Misc.Swap的类型报告为:

public static void Swap<a>(ref a left, ref a right);

所以我们在这里可以看到编译器已将curried参数转换为tupled形式。

使用tupled参数定义方法可以避免此问题:

type Misc =
    static member Swap(left : 'a byref, right : 'a byref) =
        let temp = left
        left  <- right
        right <- temp    

> let s = Array.init 3 (fun i -> i)
> val s : int array = [|0; 1; 2|]
> Misc.Swap (&s.[2], &s.[0]) 
> s;;
> val s : int array = [|2; 1; 0|]