2015-12-23 65 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