2015-12-23 68 views
6

我已经定义了以下类型(从代码简化):类型推断未能在泛型类型的静态成员约束

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:一(^ a或^ 23604):(static> member(+):^ a *^23604 - >^23605)'

关于单词“更长”在最后一行。据我所知,它应该能够推断出它总是添加两个'a'成员。 我该如何摆脱这个?

回答

3

这是一个有趣的问题,使用let绑定函数而不是静态成员似乎不会触发相同的警告。推测在允许绑定和成员函数中静态类型参数的解析存在差异。

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 

基于上述让利约束功能与+运营商可以再延长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 
+0

不错的解决方法。 – FZed