19

Ich habe mich gefragt, ob es möglich ist, mehrere Male mit den gleichen Werten zu vergleichen, und zwar mit dem Mustervergleich der funktionalen Programmiersprachen (Haskell/F #/Caml).Muster, das mit identischen Werten übereinstimmt

Man denke nur an folgendem Beispiel:

plus a a = 2 * a 
plus a b = a + b 

Die erste Variante würde aufgerufen werden, wenn die Funktion mit zwei ähnlichen Werten aufgerufen wird (das in a gespeichert werden würde).

Eine nützlichere Anwendung wäre dies (vereinfacht eine AST).

simplify (Add a a) = Mult 2 a 

Aber Haskell lehnt diese Codes und warnt mich über widersprüchlichen Definitionen für a - Ich habe stattdessen expliziter Fall/if-Kontrollen zu tun, um herauszufinden, ob die Funktion identische Werte einsehen. Gibt es einen Trick, um anzuzeigen, dass eine Variable, mit der ich übereinstimmen möchte, mehrmals vorkommen wird?

+0

FWIW, Mathematica unterstützt dies. –

Antwort

39

Dies wird nichtlineare Muster genannt. Es gibt einige Threads auf der Haskell-Cafe-Mailing-Liste darüber, nicht lange her. Hier sind zwei:

http://www.mail-archive.com/[email protected]/msg59617.html

http://www.mail-archive.com/[email protected]/msg62491.html

Fazit: es ist nicht unmöglich zu implementieren, wurde aber entschieden gegen die Einfachheit halber.

Übrigens brauchen Sie nicht if oder case, um dies zu umgehen; die (leicht) cleane Art und Weise ist eine Wache zu verwenden:

a `plus` b 
    | a == b = 2*a 
    | otherwise = a+b 
+0

Danke für die Links - Excellent – Dario

13

Sie können nicht zwei Parameter mit dem gleichen Namen haben, um anzuzeigen, dass sie gleich sein sollten, aber Sie guards Fälle zu unterscheiden wie diese verwenden:

plus a b 
    | a == b = 2 * a 
    | otherwise = a + b 

für Dies ist flexibler, da es funktioniert auch kompliziertere Bedingungen als einfache Gleichheit.

+0

Ja, ich kenne Wachen, aber ich habe versucht, jeden manuellen Vergleich zu vermeiden. – Dario

+0

Kinda Abkürzung dafür: http: // Stackoverflow.com/questions/480769/f-Matching-mit-zwei-Werte/501541 # 501541 – Dario

-1

Haskell macht keine Vereinigung.

+4

Es würde freie Variablen auf beiden Seiten zur Vereinheitlichung benötigen. –

+1

Dies ist nur die Gleichheit, nicht die Vereinigung. Wie '| a, a wenn a = a -> .. '. –

0

Ich habe gerade die Mailingliste Themen in Thomas Antwort, und die erste Antwort in einem von ihnen machen guten Sinn gegeben nachgeschlagen, und erklärt, warum solche ein "Muster" würde im Allgemeinen nicht viel Sinn machen: Was ist, wenn a eine Funktion ist? (Es ist im Allgemeinen unmöglich, zu überprüfen, ob zwei Funktionen gleich sind.)

+0

Könnte es nicht einfach "a" zu "Eq" sein? – gdejohn

+0

@gdejohn, ich vermute, dass die Semantik nicht richtig wäre. Wenn man eine Definition der Form 'fxx = x' anwendet, könnte man IMO vernünftigerweise erwarten, dass die beiden übergebenen Argumente * der gleiche Wert * und nicht nur" gleich "im Sinne einer Typklasse sind (sonst ist nicht einmal klar, was von den zwei Werten von "x" sollte "f" zurückkehren. – Alexey

-1

Ich habe eine neue funktionale Programmiersprache implementiert, die nichtlineare Muster in Haskell verarbeiten kann.

https://github.com/egison/egison

In meiner Sprache, Ihre plus Funktion in wie folgt geschrieben.

(define $plus 
    (match-lambda [integer integer] 
    {[[$a ,a] (* a 2)] 
    [[$a $b] (+ a b)]})) 
Verwandte Themen