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

Why inline static type resolution does not work on List?

我正在尝试编写一个内联映射函数,该函数可用于任何具有 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) 这一行引起编译器警告,但是前面的表达式没问题!?错误信息是

The type 'int list' does not support operator mapx

谁能解释为什么它对 List 不起作用但对 Container 起作用?以及我必须做些什么才能使其与 List 一起使用?

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

谢谢!

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

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