2016-06-01 16 views
6

Dies ist eine rein akademische Frage, aber Riffing von this question über Typ Einschränkungen. Der Fragesteller gab dies als ein Beispiel:Es ist unmöglich, ein Objekt mit einer rekursiven Typabhängigkeit zu erstellen.

type Something<'a, 'b when 'b :> seq<'b>>() = 
    member __.x = 42 

die f # glücklich kompiliert. Jetzt ist das Problem, wie machst du dieses Objekt?

let z = new Something<???, ???>() 
+3

Siehe https://msdn.microsoft.com/en-us/library/documentformat.openxml.openxmlelement(v=office.14).aspx für ein nicht-erfundenes Beispiel von eine Klasse, die benutzt werden könnte. – kvb

+1

Vielleicht sollten Sie den Titel ändern, um das Wort "Impossible" zu entfernen, versuchen Sie "Kann mich nicht um diesen einen Kopf bekommen" –

+0

@ kvb Sie haben Recht. 'let z = new Etwas ()' funktioniert – Ray

Antwort

3

Hier ist eine Art und Weise:

open System.Collections.Generic 

type Node<'a>() = 
    let getEmptyEnumerator() = Seq.empty<Node<'a>>.GetEnumerator() 
    interface IEnumerable<Node<'a>> with 
     member this.GetEnumerator() = getEmptyEnumerator() 
     member this.GetEnumerator() = 
      getEmptyEnumerator() :> System.Collections.IEnumerator 

Statt die leere Folge der Rückkehr Sie diese Klasse implementieren könnte eine Folge von untergeordneten Knoten zurückzukehren. Ich nannte diesen Typ Node<'a>, weil es eine ziemlich idiomatische Methode ist, einen Baum (oder ein Diagramm) in C# zu modellieren.

Verwendung:

> let smth = Something<string, Node<int>>();;  
val smth : Something<string,Node<int>> 

> smth.x;; 
val it : int = 42 
4
type T() = 
    interface seq<T> with 
     member this.GetEnumerator() = ([] :> seq<T>).GetEnumerator() 
     member this.GetEnumerator() = ([] :> seq<T>).GetEnumerator() :> System.Collections.IEnumerator 

let z = new Something<string, T>()