我想在我自己的类中实现IEnumerable<KeyValuePair<DateTime, 'T>>
并向该类添加数学运算符,以便运算符可以像'T
的任何数值类型一样工作,就像自动添加约束一样。
我只是无法使下面的代码工作。在成员声明中,它既没有“内联”关键字也没有。
另外,如果我定义一个函数
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)
答案 0 :(得分:6)
你的方法对我来说似乎是正确的。
您的代码无法编译的原因是因为F#类型推断推断出类型变量'T
的静态约束(编译时),它与类型定义相同。
无法静态解析类型定义的泛型参数(没有“hat”类型),但没有什么能阻止您定义使用这些编译时约束的函数或成员。
只需在静态成员'T
定义中将类型变量'U
更改为(+)
,就可以了。
您仍然可以创建一个不支持TimeSeries
的类型(+)
实例(例如:TimeSeries<obj>
),但您将无法使用{{1}对于那些实例,无论如何,如果你这样做,你将在编译时得到一个很好的错误信息。