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 に答える