2012-12-24 32 views
8

我想在自己的类中实现IEnumerable<KeyValuePair<DateTime, 'T>>,并将数学运算符添加到该类中,以便运算符可以在任何数字类型的'T上像内联函数一样工作 - 自动添加约束。f#类型成员中的静态解析类型

我只是不能使下面的一段代码工作。它在成员声明中既没有也没有“inline”关键字。

另外,如果我的类型之前定义一个函数

let inline add l r = l + r 

,并用它来代替另外l.Value + r.Value的,它也不起作用。

有人能告诉我我做错了什么吗?

可能整个方法都是错误的,并且有办法以另一种方式实现相同的目标?

namespace Test 

open System 
open System.Linq 
open System.Collections.Generic 

[<SerializableAttribute>] 
type TimeSeries<'T>(dictionary : IDictionary<DateTime, 'T>) = 
    let internalList = new SortedList<DateTime, 'T>(dictionary) 
    interface IEnumerable<KeyValuePair<DateTime, 'T>> with 
     member this.GetEnumerator() = internalList.GetEnumerator() 
     member this.GetEnumerator() : Collections.IEnumerator 
      = internalList.GetEnumerator() :> Collections.IEnumerator 
    member private this.sl = internalList 
    static member inline (+) (left : TimeSeries<'T>, right : TimeSeries<'T>) = 
     let res = 
      query { 
      for l in left do 
      join r in right on 
       (l.Key = r.Key) 
      select (l.Key, l.Value + r.Value)  
      } 
     new TimeSeries<'T>(res |> dict) 
+3

下面是我知道的最简单的答案:http://tomasp.net/blog/fsharp-generic-numeric.aspx复杂的主题。 –

回答

6

你的方法对我来说似乎是正确的。 您的代码无法编译的原因是因为F#类型推断正在推导类型变量'T的静态约束(编译时),它与用于类型定义的类型变量相同。

类型定义的泛型参数不能静态解析(没有“帽子”类型),但没有任何东西阻止您定义函数或使用这些编译时约束的成员。

只需将静态成员(+)定义中的类型变量'T更改为'U即可。

不过你还是被允许创建不支持(+)一个类型(即:TimeSeries<obj>)的TimeSeries实例,但你将无法使用(+)这些情况下,无论如何,如果你这样做,你会得到编译时一个很好的错误信息。

+0

太棒了!有用!非常感谢! –