Frage

Ich bin hier, um ein bestimmtes Thema fragen - ich wirklich wenige Informationen über diese im Internet gefunden. Ich bin ein F # Version von Minimax-Algorithmus implementiert. Das Problem, das ich jetzt habe, ist, dass ich Blatt von meinem Baum (Datenstruktur unten) vergleichen möge. Durchsuchen der erros der VS gab mir kam ich zu so etwas wie folgt aus:

Der Baum Typ I verwendet hat:

type TreeOfPosition =
    | LeafP   of Position
    | BranchP of Position * TreeOfPosition list

und die temptative für die Umsetzung der IComparable

type staticValue = int
[<CustomEquality;CustomComparison>]
type TreeOfPosition =
    | LeafP   of Position * staticValue
    | BranchP of Position * TreeOfPosition list

    override x.Equals(yobj) = 
        match yobj with
        | :? TreeOfPosition as y -> (x = y)
        | _ -> false

    override x.GetHashCode() = hash (x)
    interface System.IComparable with
        member x.CompareTo yobj =
            match yobj with
            | :? TreeOfPosition as y -> compare (x) (y)
            | _ -> invalidArg "yobj" "cannot compare value of different types"

Am Ende bekommt ich mag nur den max (und die min) aus einer Liste von LeafP durch ihren statischen Wert (calculate in anderer Funktion).

Der obige Code kompiliert. Doch mit dieser Prüfung:

let p = new Position()
p.Add(1,BLACK)
let a = LeafP(p,1)
let b = LeafP(p,2)

let biger = compare a b
printf "%d" biger

habe ich einen System.StackOverflowException in der "|: TreeOfPosition als y -> vergleichen (x) (y)". Zeile in der Überschreibung des GetHashCode

habe ich einen Thread im hubfs.net ( http: //cs.hubfs. net / Foren / thread / 15891.aspx ) mit mir meine Minimax bin zu diskutieren. //www.inf.ufrgs: Hier können Sie meine neuesten Code ( http finden. br / ~ pmdusso / Werke / Functional_Implementation_Minimax_FSharp.htm )

Vielen Dank im Voraus,

Pedro Dusso

Nun, verstand ich sehr deutlich die Idee, aber ich kann es nicht funktioniert. Daran erinnernd, dass ich das Blatt mit dem maximalen statischen Wert aus einer Liste von Blättern ( „List.max“: P) erhalten will, denke ich, die CompareTo oder Equals Umsetzung werde die List.max arbeitet an sie, zu korrigieren lassen? Ich komponiere die Dinge wie diese:

let mycompare x y = 
  match x, y with
  // Compare values stored as part of your type
  | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2
  //| BranchP(_, l1), BranchP(_, l2) -> compare l1 l2 //I do not need Branch lists comparison
  | _ -> 0 // or 1 depending on which is list...

[< CustomEquality;CustomComparison >]
type TreeOfPosition =
    | LeafP   of Position * int
    | BranchP of Position * TreeOfPosition list

    override x.Equals(yobj) = 
       match yobj with
       | :? TreeOfPosition as y -> (x = y)
       | _ -> false

    override x.GetHashCode() = hash (x)
    interface System.IComparable with
       member x.CompareTo yobj = 
          match yobj with 
          | :? TreeOfPosition as y -> mycompare x y
          | _ -> invalidArg "yobj" "cannot compare value of different types" 

Die Probleme, das ich habe, die Funktionen auf diese Weise der Anordnung ist:

1) Der Muster-Diskriminator 'LeafP' nicht definiert ist (mit LeafP rot unterstrichen)

2) (77,39): Fehler FS0039: Der Wert oder Konstruktor 'mycompare' ist nicht definiert, wenn ich versuche, ein ALT Diese Nachricht in meinem F # Interactive erscheint ENTER. Die Position {77,39} entspricht den Anfang mycompare Aufruf (in GetHashCode).

Was mache ich falsch? Was kann ich besser machen?

Vielen Dank,

Pedro Dusso

EDIT 3 - Gelöst

Ja! Ich schaffe Ihre Antwort auf Arbeit finaly!

Der letzte Code ist hier:

[<CustomEquality;CustomComparison>]
type TreeOfPosition =
    | LeafP   of Position * int
    | BranchP of Position * TreeOfPosition list

    //Func: compare
    //Retu: -1: first parameter is less than the second
    //       0: first parameter is equal to the second
    //       1: first parameter is greater than the second
    static member mycompare (x, y) = 
        match x, y with
        // Compare values stored as part of your type
        | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2
        | _ -> 0 // or 1 depending on which is list...

    override x.Equals(yobj) = 
        match yobj with
        | :? TreeOfPosition as y -> (x = y)
        | _ -> false

    override x.GetHashCode() = hash (x)
    interface System.IComparable with
       member x.CompareTo yobj = 
          match yobj with 
          | :? TreeOfPosition as y -> TreeOfPosition.mycompare(x, y)
          | _ -> invalidArg "yobj" "cannot compare value of different types" 

Danke für das Feedback!

Pedro Dusso

War es hilfreich?

Lösung

Zunächst einmal, Sie bekommen die Ausnahme, da die compare Funktion die CompareTo Methode des Wertes rufen Sie vergleicht (der x.ComaperTo(y) ist). Die Werte, die Sie verwenden compare in der benutzerdefinierten Implementierung von CompareTo Vergleich sind die Werte, die Sie gefragt werden, vergleichen (von der Laufzeit), so dass dieser den Stapelüberlauf verursacht.

Der üblicher Weg CompareTo oder Equals zu implementieren, ist nur einige Werte zu vergleichen, dass Sie in Ihrer Art speichern. Zum Beispiel könnte man so etwas schreiben:

Bearbeiten : Sie können eine Hilfsfunktion mycopare schreiben den Vergleich zu tun (oder man könnte einfach die CompareTo Implementierung ändern). Wenn Sie jedoch eine Funktion verwenden möchten, müssen Sie es in der Typdeklaration bewegen (so dass es über den Typ weiß - beachten Sie, dass in F #, die Reihenfolge der Deklaration Sachen)

Eine Möglichkeit, es zu schreiben, ist dies:

[<CustomEquality; CustomComparison >] 
type TreeOfPosition = 
  | LeafP   of Position * int 
  | BranchP of Position * TreeOfPosition list 

  override x.Equals(yobj) =  
     match yobj with 
     | :? TreeOfPosition as y -> 
        // TODO: Check whether both y and x are leafs/branches
        // and compare their content (not them directly)
     | _ -> false 
  override x.GetHashCode() = // TODO: hash values stored in leaf/branch

  interface System.IComparable with 
     member x.CompareTo yobj =  

       // Declare helper function inside the 'CompareTo' member
       let mycompare x y = 
         match x, y with
         // Compare values stored as part of your type
         | LeafP(_, n1), LeafP(_, n2) -> compare n1 n2
         | BranchP(_, l1), BranchP(_, l2) -> compare l1 l2
         | _ -> -1 // or 1 depending on which is list...

       // Actual implementation of the member
       match yobj with 
       | :? TreeOfPosition as y -> mycompare x y
       | _ -> invalidArg "yobj" "cannot compare value of different types" 

Das würde funktionieren, weil jeder Anruf zu compare nur einen Teil der Daten übernimmt, so dass Sie einige Fortschritte machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top