8

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

我只是无法使以下代码工作。在成员声明中使用或不使用 '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)
4

1 回答 1

6

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

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

只需将您的类型变量更改'T'U静态成员(+)定义中的,就可以了。

您仍然可以创建TimeSeries不支持的类型的实例(+)(即:)TimeSeries<obj>,但您将无法使用(+)这些实例,无论如何,如果您这样做,您将在编译时收到一条很好的错误消息.

于 2012-12-25T21:58:03.390 回答