为什么内联静态类型解析在List上不起作用?

时间:2015-08-11 02:50:55

标签: generics f# inline typeclass

我正在尝试编写一个内联映射函数,该函数可以与mapx作为静态成员的任何类型一起使用,并具有以下代码:

type Container<'T> =
  { value: 'T }

type container<'a> = Container<'a>

type Container<'T> with
  static member mapx (f: 'T -> 'b,  x: 'T container) = { value=f(x.value) } // tuple form...

type List<'T> with
  static member mapx (f: 'T -> 'b, x: 'T list) = List.map f x

let inline map (f: ^a -> ^b) (x: ^t) =
  (^t: (static member mapx: (^a -> ^b) -> ^t -> ^c ) (f, x))  // (2) curry form

let plus2 = (+) 2

let x = { value=2 } |> map plus2  // ok
let y = [1;2;3] |> map plus2      // (1) Error... 

printfn "%A" x
printfn "%A" y

我有两个问题:

(1)这一行导致编译器警告,但前一个表达式没问题!?错误消息是

  

类型'int list'不支持operator mapx

任何人都可以解释为什么它在List上不起作用但对Container有效吗?以及如何使其与List一起使用?

(2)我正确使用约束吗?我发现约束是用咖喱形式写的,但方法必须是元组形式......这很混乱。

谢谢!

1 个答案:

答案 0 :(得分:1)

F#不支持扩展成员的静态解析类型约束,这就是List不起作用的原因。

当编译器可以时,它会将扩展语法成员编译为普通成员,这就是Container工作的原因。