0

私はこのような単純なタイプを持っています:

/// <summary>
/// An attribute consists of a key and all possible values.
/// </summary>
type IAttribute<'a when 'a: comparison> =
    abstract Key: string
    abstract Values: seq<'a>

この定義から、次のような実装を作成します。

let numericAttribute values =
    { new IAttribute<float> with
        member this.Key = "Numeric"
        member this.Values = values }

let enumerationAttribute values =
    { new IAttribute<string> with
        member this.Key = "Enumeration"
        member this.Values = values }

例:

let numAttr = numericAttribute [| 1.0; 4.0; 6.0; 20.0; 70.0 |]
let enAttr = enumerationAttribute [| "val1"; "val2"; "val3" |]

これで、インスタンスを作成できます。

let num1 = new AttributeInstance<float>(numAttr, 4.0)
let num2 = new AttributeInstance<float>(numAttr, 6.0)
let en1 = new AttributeInstance<string>(enAttr, "val1")

AttributeInstanceは、特定の属性タイプのタプルであり、その属性タイプと互換性のある値であるタイプです。

私はこれに沿った単純なツリーが欲しいです:

type Tree<'a when 'a: comparison> =
| Leaf of 'a
| SubTree of AttributeInstance<'a> * seq<Tree<'a>>

私の問題は、ツリーのさまざまなレベルで、さまざまなタイプを使用できるようにしたいということです。あるレベルでは、属性がen1であるサブツリーが必要であり、次のレベルでは、num1(またはnum2)を持つことができるようにする必要があります。

誰かが私がこれを一般化または再考するのを手伝ってもらえますか?

4

1 に答える 1

3

問題は、次のようなものを書き込もうとした場合です。

|Subtree of 'a * seq<Tree<'b>>

'b最終的には、コンパイラがサポートしていない型の無限のチェーンのようなものを作成する可能性のある新しい型になります。

これを行う1つの方法は、可能なタイプをユニオンでラップすることです-次のようなもの

type Element = 
    |....

そしてあなたの木は

type Tree =
| Leaf of Element
| SubTree of AttributeInstance<element> * seq<Tree>

または、マルチジェネリックツリーを作成することもできます。

type Tree<'a,'b,'c,'d> =
| Leaf1 of 'a
| Leaf2 of 'b
...
| SubTree of AttributeInstance<'a> * seq<Tree<'a,'b,'c,'d>>
于 2012-08-26T11:27:17.587 に答える