Gibt es eine schnelle und einfache Möglichkeit, die Priorität und Assoziativität einer Funktion in GHCI zu erkennen?Wie erkennt man die Priorität und Assoziativität einer Funktion in GHCI?
Ich habe festgestellt, dass eine einfache Methode Bruteforce ist, einen Operator mit einem anderen zu kombinieren, bis Sie einen Precedence Parsing Error (PPE) erhalten. Um zum Beispiel den Vorrang/Assoziativität von !!
zu entdecken, können wir 10 verschiedene Betreiber von infix n
für 0 ≤ n < 10
definieren:
>>> let infix 0 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
>>> let infix 1 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
[...]
>>> let infix 8 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
>>> let infix 9 %; (%) = ($)
>>> undefined % undefined !! undefined
<interactive>:21:1:
Precedence parsing error
cannot mix `%' [infix 9] and `!!' [infixl 9] in the same infix expression
Der Fehler sagt Ihnen, was die predences und fixities sind. Da die 10 definierten Funktionen nicht assoziativ sind, gibt es keine Möglichkeit, eine PPE zu vermeiden, wenn die Rangstufen gleich sind. Der naive Ansatz wäre gewesen, 10 Funktionen jeder Assoziativität auszuprobieren, was zu einem WCET von 20 führt (denn wenn man auf der gleichen Assoziativität wie das Ziel anfängt, würde die 10 mit dieser Assoziativität bestehen, aber dann würde der Fehler passieren, wenn du erst einmal kommst der kth
Vorrang der nächsten Assoziativität, wobei k
der Vorrang der Zielfunktion ist).
Aber gibt es einen schnelleren Weg? I Denken Sie Sie können Bisektion im Durchschnitt Log (10) Schritte zu erreichen. Wenn das Ziel beispielsweise !!!
ist, das als !!
definiert ist, aber mit infixl 6
, könnten wir einen Ausdruck (:[]) % "AB" !!! 1
machen, wobei %
eine der gleichen 10 Dummy-Funktionen ist. Wenn der Vorrang von %
zu niedrig ist, um ein PPE zu verursachen, liefert der Ausdruck "B"
(weil der Ausdruck zu (:[]) % ("AB" !!! 1)
analysiert), während, wenn der Vorrang zu hoch ist, ⊥
(weil der Ausdruck zu ((:[]) % "AB") !!! 1
parsen wird). Beispiel:
>>> let infixl 6 !!!; (!!!) = (!!)
>>> let infix 5 %; (%) = ($)
>>> (:[]) % "AB" !!! 1
"B"
>>> --too low
>>> let infix 7 %; (%) = ($)
>>> (:[]) % "AB" !!! 1
"*** Exception: Prelude.(!!): index too large
>>> --too high
>>> let infix 6 %; (%) = ($)
>>> (:[]) % "AB" !!! 1
<interactive>:10:1:
Precedence parsing error
cannot mix `%' [infix 6] and `!!!' [infixl 6] in the same infix expression
>>> --got it
Allerdings bin ich nicht sicher über diesen Ansatz.
- Sie haben die Befindlichkeit, deren Anzahl zu halten nächsten zu erraten, und tun, um die Abteilung usw. in Ihrem Kopf (von Papier/Rechner würde wahrscheinlich langsamer sein als nur die 10 Schritte in der einfachen Methode zu tun)
- Ist es völlig allgemein? Kannst du einen Testausdruck immer so aufbauen?
- Ich bin mir nicht sicher, ob ich mit einem solchen Ausdruck immer schneller kommen kann als mit der einfachen Methode. In diesem Fall war es tatsächlich schneller, und ich kam tatsächlich mit der Halbierung Methode vor Ich kam mit der einfachen Methode
- Wenn das vorherige Anliegen gilt, gibt es eine völlig allgemeine Möglichkeit, Ausdrücke davon automatisch zu generieren nett?
Kennt jemand eine alternative Methode? Ich kann mir vorstellen, dass es einen Weg geben könnte, dies in einem einzigen Schritt zu tun. Aber nach einer Stunde ist das Beste, was ich mir vorstellen kann, diese Halbierungsmethode.
Sie können auch nur eingeben, z. B. ': i +'. –