Difference between revisions of "De/Flussrichtung"

From HaskellWiki
Jump to navigation Jump to search
(Weblinks)
(Category:De/Syntax)
 
(One intermediate revision by the same user not shown)
Line 59: Line 59:
 
derive f x :: a
 
derive f x :: a
 
</haskell>
 
</haskell>
Wir können gewissermaßen die Argumente von der Typseite auf die
+
Wir können gewissermaßen die Argumente von der Typseite auf die
 
Werteseite umschichten. Die Argumentreihenfolge ist daher in
 
Werteseite umschichten. Die Argumentreihenfolge ist daher in
 
Typsignatur und Funktionsanwendung gleich. Bei der konsequenten
 
Typsignatur und Funktionsanwendung gleich. Bei der konsequenten
Line 68: Line 68:
 
x f derive :: a
 
x f derive :: a
 
</haskell>
 
</haskell>
Die Notation hat natürlich den unbestreitbaren Vorteil, dass man sich
+
Die Notation hat natürlich den unbestreitbaren Vorteil, dass man sich
 
<hask>::</hask> wie ein Gleichheitszeichen vorstellen kann, wo man auf beiden Seiten
 
<hask>::</hask> wie ein Gleichheitszeichen vorstellen kann, wo man auf beiden Seiten
 
der Gleichung die Ausdruecke immer von links manipuliert.
 
der Gleichung die Ausdruecke immer von links manipuliert.
Line 77: Line 77:
 
* http://www.iba-cg.de/doc/hal1-haskell-with-style.pdf
 
* http://www.iba-cg.de/doc/hal1-haskell-with-style.pdf
   
  +
== Siehe auch ==
   
  +
[[Direction of data flow]]
[[Category:Syntax]]
 
  +
 
[[Category:De/Syntax]]

Latest revision as of 12:46, 20 March 2007

Es wurde hin und wieder bemängelt, dass die symbolisierten Datenflussrichtungen verschiedener syntaktischer Konstrukte in Haskell voneinander abweichen. Es gibt in Haskell beide Richtungen in etwa gleich häufig:

links nach rechts:

Funktionsdefinition f x = x*x (links Eingabe, rechts Ausgabe)
Lambda \ x -> x*x
do-notation do f; g
monadische Verkettung f >>= g

rechts nach links:

Funktionsanwendung f x, f $ x (rechts Eingabe, links darauf angewendete Transformation)
Verkettung g . f
Ergebnisse von Monaden do x <- f
monadische Verkettung g =<< f

Lambda-Ausdrücke sähen viel natürlicher aus, wenn die Verkettung von links nach rechts gehen würde, also statt

  transform3 . (\x -> transform2 x x)  . transform1

besser

  transform1 . (\x -> x x transform2)  . transform3

Auch

 do f -> x; g x

wäre schon viel näher an der darunterliegenden Implementierung

 f >>= \x -> g x


Allerdings sehe ich noch zwei Unschönheiten/Gewöhnungsbedürftigkeiten:

Eines tritt beim Lesen von links-nach-rechts-Ausdrücken auf: Man sieht bei der Verwendung von Funktionen höherer Ordnung nicht sofort, wo die Argumente eines Funktionsaufrufes aufhören. Mein Lieblingsbeispiel - der Differentialoperator derive:

 derive :: (a -> a) -> (a -> a)

Wenn man den Ausdruck x f derive nur bis f liest, denkt man, es handelt sich um die Anwendung von f auf x und danach kommt noch irgendwas. Aber nein, durch derive wird alles umgekrempelt. Man muss also einen Ausdruck erst bis zum nächsten Absatz (schließende Klammer, Infixoperator) lesen, bis man weiß, um welchen Funktionsaufruf es sich eigentlich handelt.

Die zweite Sache ist die Verbindung von Typsignatur und Funktionsanwendung. Wir schreiben

 derive :: (a -> a) -> (a -> a)
 derive f :: a -> a
 derive f x :: a

Wir können gewissermaßen die Argumente von der Typseite auf die Werteseite umschichten. Die Argumentreihenfolge ist daher in Typsignatur und Funktionsanwendung gleich. Bei der konsequenten links-nach-rechts-Notation ist das nicht mehr der Fall:

     derive :: (a -> a) -> (a -> a)
   f derive :: a -> a
 x f derive :: a

Die Notation hat natürlich den unbestreitbaren Vorteil, dass man sich :: wie ein Gleichheitszeichen vorstellen kann, wo man auf beiden Seiten der Gleichung die Ausdruecke immer von links manipuliert.

Weblinks

Siehe auch

Direction of data flow