F#缺少类型约束

bri*_*rns 2 f# type-constraints

在以下代码中,请注意get_Zero的类型约束:

type Wrapper<'t> = { Data : 't[] }

let compute<'t
    when 't : (static member get_Zero : unit -> 't)
    and 't : (static member (~-) : 't -> 't)
    and 't : (static member (+) : 't * 't -> 't)>
        (wrapper : Wrapper<'t>) =
    wrapper.Data
        |> Seq.mapi (fun i value -> (i, value))
        |> Seq.sumBy (fun (i, value) ->
            if i % 2 = 0 then value
            else -value)
Run Code Online (Sandbox Code Playgroud)

即使我已经有一个显式类型约束,我仍然在调用Seq.sumBy时遇到以下编译器错误:

类型参数缺少约束'when ^ t :(静态成员get_Zero: - > ^ t)'

谁知道这里发生了什么?谢谢.

Dan*_*iel 10

试图明确下游静态成员约束可能是一种挫败感,幸运的是,它很少是必要的.只需标记该功能inline并让它们被推断.

let inline compute (wrapper : Wrapper<_>) =
    wrapper.Data
    |> Seq.mapi (fun i value -> (i, value))
    |> Seq.sumBy (fun (i, value) ->
        if i % 2 = 0 then value
        else -value)
Run Code Online (Sandbox Code Playgroud)

正确的签名是:

let inline compute<'t
            when 't : (static member Zero : 't)
            and 't : (static member (~-) : 't -> 't)
            and 't : (static member (+) : 't * 't -> 't)>
Run Code Online (Sandbox Code Playgroud)

(您会注意到错误消息中的签名甚至不是有效的语法:when ^t : (static member get_Zero : -> ^t).这是我所说的令人沮丧的一部分.)