2016-11-22 2 views
0

Ich lerne Julia und zu diesem Zweck baue ich eine Simulation eines Schedulers für einige nicht spezifizierte Aufgabe. Dazu möchte ich einen abstrakten Typus erstellen, der die Idee des Staates repräsentiert. Eine Aufgabe, in jedem Staat sein könnte angenommen, Unerfüllte, Laufen, Abschluss:Polymorphe Funktionen und Subtypen in Julia

abstract RequestState 

Dann füge ich einige konkrete Staaten, die Request als Super haben:

immutable StateAccepted <: RequestState 
     name :: String 
end 

Und weil jeder Zustand unveränderlich ist und sowieso es nicht eine interessante Struktur haben, sind alle Instanzen gleich sind, so dass ich instanziiert eine Instanz der oben genannten Art zu verwenden:

const Accepted = StateAccepted("Accepted") 

ich dies, mit einem Makro generieren es vielleicht ist relevant.

Jetzt kommt das Problem. Ich möchte eine Funktion schreiben, die gültige Übergänge prüft. Ich habe nur ein Skelett an dieser Stelle:

function checkTransition{T <: RequestState, Q <: RequestState}(t :: T, q :: Q) :: Bool 
    return true 
end  

Ich nahm ich den Ausdruck sollte lauten:

T <: RequestState 

Wie so etwas wie forall T, die ein Subtyp von Request ist, aber ich denke, das ist falsch.

Ich würde erwarten, dass dieser Code kompiliert. Das Problem ist, dass ich den Fehler nicht verstehe und auch nichts in der Dokumentation finden kann. Beachten Sie, dass dies sein könnte, weil ich mit der Sprache nicht vertraut bin. Der entsprechende Fehler ist:

Error During Test 
    Expression evaluated to non-Boolean 
    Expression: checkTransition(Accepted,Running) 
    Value: ResourceScheduler.StateRunning("Running") 
ERROR: LoadError: There was an error during testing 
    in record(::Base.Test.FallbackTestSet, ::Base.Test.Error) at  ./test.jl:397 
    in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281 
    in include_from_node1(::String) at ./loading.jl:488 
    in process_options(::Base.JLOptions) at ./client.jl:262 
    in _start() at ./client.jl:318 
    while loading /home/eklerks/.julia/v0.5/ResourceScheduler/test/runtests.jl 

Wie würde ich eine generische Funktion zu akzeptieren nur Argumente der Subtypen von Request machen?

EDIT:

Wie gewünscht wird der säumige Test:

@test checkTransition(Accepted, Running) 

Aber diese aus funktionierte nicht, weil ich mein Paket zu aktualisieren, vergessen und zu installieren, nachdem ich es geändert. Vor dieser Änderung stand:

function checkTransition{T <: RequestState, Q <: RequestState}(t :: T, q :: Q) :: Q 
    return q 
end 

Welches war die Quelle des Fehlers. Typ Q ist in der Tat kein Boolescher Wert. Ich habe in diesem Moment mit dem Typsystem experimentiert.

+1

Sie müssen den Test für uns veröffentlichen, um zu wissen, warum dies fehlschlägt. –

Antwort

4

Während Ihr Code funktionieren sollte, schreibt man in der Regel

checkTransition(t::RequestState, q::RequestState) = true 

stattdessen die unnötige T <: RequestState Parametrierung der Verwendung. Beachten Sie, dass f{T <: X}(::T) nicht als "für alle T Subtyp von X" gelesen werden sollte, sondern "T Subtyp von X" existiert, da dies ein existential type und kein universeller Typ ist.

Der Fehler, den Sie bekommen, ist auf checkTransition(Accepted,Running) zurückzuführen, die einen nicht booleschen Wert zurückgibt, der auf einen Fehler zurückzuführen sein muss, der nicht mit dem von Ihnen geposteten Code zusammenhängt.

+0

Ah danke, ich wusste, dass es etwas Dummes sein musste. Ich fügte den fehlerhaften Code hinzu und dokumentierte den Fehler, den ich gemacht hatte. Und danke, dass du darauf hingewiesen hast, dass es kein universeller Typ ist, den ich eigentlich hier schreiben wollte. –

+0

Das ist ein interessanter Kommentar bezüglich der existentiellen vs universellen Quantifizierung ... aber ich habe Mühe, über einen praktischen Unterschied zwischen den beiden nachzudenken, oder einen Fall, wo diese Unterscheidung im Zusammenhang mit Typen und Julia-Code von Bedeutung ist. Gibt es ein Szenario, in dem das Deklarieren von T als Untertyp von R weiterhin einige Subtypen von R als gültige Parameter ausschließt? (natürlich, bevor ein solcher Ausschluss in der nachfolgenden Funktionsdefinition explizit gemacht wird). Oder machen Sie einfach einen Kommentar darüber, wie man das Konzept der "Template" -Typen unter semantischen Gesichtspunkten interpretieren sollte? –

+1

@TasosPapastylianou Existentialtypen und Universaltypen haben in der Typentheorie spezifische Bedeutungen. Ein Objekt ist vom Typ 'Vector {T}, wobei T 'zum Beispiel ist, wenn dort ein' T 'existiert, so dass das Objekt vom Typ' Vektor {T} 'ist. Ein Objekt würde vom Typ "Vektor {T} für alle T" sein (vorausgesetzt, dass es existiert), wenn für jedes "T" das Objekt vom Typ "Vektor {T}" ist; In Julia gibt es keine Objekte, die dieses Kriterium erfüllen. –

Verwandte Themen