【问题标题】:Type inference failing on generic type with static member constraint具有静态成员约束的泛型类型的类型推断失败
【发布时间】:2016-03-29 21:54:01
【问题描述】:

我定义了以下类型(从代码简化):

type Polynomial<'a when 'a :(static member public Zero : 'a) 
                and 'a: (static member (+): 'a*'a -> 'a) 
                and 'a : (static member (*): 'a*'a -> 'a) >  =
    | Polynomial of 'a list
    with 
    static member inline (+) (x: Polynomial<'a> , y : Polynomial<'a>) : Polynomial<'a>= 
        match x,y with
        |Polynomial xlist, Polynomial ylist ->
            let longer, shorter = 
                if xlist.Length> ylist.Length then xlist, ylist
                else ylist, xlist
            let shorterExtended = List.append shorter (List.init (longer.Length - shorter.Length) (fun _ -> LanguagePrimitives.GenericZero<'a>))
            List.map2 (+) longer shorterExtended |> Polynomial

当我构建时,我收到警告:

警告 FS0193:类型参数缺少约束 'when ( ^a or ^?23604) : (static >member ( + ) : ^a * ^?23604 -> ^?23605)'

在最后一行的“更长”这个词上。据我所见,它应该能够推断出它总是添加两个成员'a。 我怎样才能摆脱它?

【问题讨论】:

    标签: generics f# type-inference


    【解决方案1】:

    这是一个有趣的问题,使用let 绑定函数而不是静态成员似乎不会触发相同的警告。想必 let bound 和成员函数中静态类型参数的解析是有区别的。

    module PolyAdder =
        let inline addPoly x y = 
            match x,y with
            |Polynomial xlist, Polynomial ylist ->
                let (longer : ^a list), (shorter : ^a list) = 
                    if xlist.Length > ylist.Length then xlist, ylist
                    else ylist, xlist
                let shorterExtended : ^a list = shorter @ (List.init (longer.Length - shorter.Length) (fun _ -> LanguagePrimitives.GenericZero< ^a >))
                // no warning here!
                List.map2 (+) longer shorterExtended |> Polynomial
    

    然后,您可以使用基于上述 let 绑定函数的 + 运算符扩展 Polynomial

    type Polynomial with
        static member inline (+) (x, y) = PolyAdder.addPoly x y
    

    依然没有警告,+号操作正常

    let poly1 = [1; 2; 5; 6; 8] |> Polynomial
    let poly2 = [7; 1; 2; 5;] |> Polynomial
    let polyAdded = poly1 + poly2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多