In F # ist die Verwendung des Pipe-Forward-Operators |>
ziemlich häufig. In Haskell habe ich jedoch nur die Funktionszusammensetzung gesehen (.)
, die verwendet wurde. Ich verstehe, dass sie verwandt sind , aber gibt es einen sprachlichen Grund, warum Pipe-Forward in Haskell nicht verwendet wird, oder ist es etwas anderes?
haskell
f#
functional-programming
composition
Ben Lings
quelle
quelle
&
Haskells ist|>
. Tief in diesem Thread vergraben und ich brauchte ein paar Tage, um es zu entdecken. Ich benutze es oft, weil Sie natürlich von links nach rechts lesen, um Ihrem Code zu folgen.Antworten:
Ich bin ein wenig spekulativ ...
Kultur : Ich denke,
|>
ist ein wichtiger Operator in der F # "Kultur", und vielleicht ähnlich mit.
für Haskell. F # hat einen Funktionskompositionsoperator,<<
aber ich denke, die F # -Community verwendet tendenziell weniger punktefreien Stil als die Haskell-Community.Sprachunterschiede : Ich weiß nicht genug über beide Sprachen, um sie zu vergleichen, aber vielleicht sind die Regeln für die Verallgemeinerung von Let-Bindungen ausreichend unterschiedlich, um dies zu beeinflussen. Zum Beispiel weiß ich in F # manchmal schreiben
wird nicht kompiliert und Sie benötigen eine explizite eta-Konvertierung:
um es kompilieren zu lassen. Dies lenkt die Menschen auch vom punktfreien / kompositorischen Stil weg und zum Pipelining-Stil. Außerdem erfordert die Inferenz vom Typ F # manchmal ein Pipelining, sodass links ein bekannter Typ angezeigt wird (siehe hier ).
(Ich persönlich finde den punktefreien Stil unlesbar, aber ich nehme an, dass jedes neue / andere Ding unlesbar erscheint, bis Sie sich daran gewöhnt haben.)
Ich denke, beide sind in beiden Sprachen potenziell lebensfähig, und Geschichte / Kultur / Unfall können definieren, warum sich jede Gemeinde bei einem anderen "Attraktor" niedergelassen hat.
quelle
.
und$
, so dass die Leute sie weiterhin benutzen.In F #
(|>)
ist wegen der Links-Rechts-Typprüfung wichtig. Beispielsweise:Im Allgemeinen wird der Typcheck nicht überprüft, da selbst wenn der Typ von
xs
bekannt ist, der Typ des Argumentsx
für das Lambda zum Zeitpunkt des Typecheckers nicht bekannt ist und daher nicht weiß, wie es aufgelöst werden sollx.Value
.Im Gegensatz
wird gut funktionieren, weil die Art von
xs
wird dazu führen, dass die Artx
bekannt ist.Die Typüberprüfung von links nach rechts ist aufgrund der Namensauflösung erforderlich, die bei Konstrukten wie z
x.Value
. Simon Peyton Jones hat einen Vorschlag geschrieben , Haskell eine ähnliche Art der Namensauflösung hinzuzufügen. Er schlägt jedoch vor, lokale Einschränkungen zu verwenden, um zu verfolgen, ob ein Typ stattdessen eine bestimmte Operation unterstützt oder nicht. In der ersten Stichprobe würde die Anforderung,x
die eineValue
Eigenschaft benötigt, so lange vorgetragen, bisxs
sie erkannt wurde und diese Anforderung gelöst werden könnte. Dies erschwert jedoch das Typsystem.quelle
Weitere Spekulationen, diesmal von der überwiegend Haskell-Seite ...
($)
ist das Umdrehen von(|>)
, und seine Verwendung ist ziemlich häufig, wenn Sie keinen punktfreien Code schreiben können. Der Hauptgrund,(|>)
der in Haskell nicht verwendet wird, ist, dass sein Platz bereits von eingenommen wird($)
.Aus ein wenig F # -Erfahrung heraus denke ich, dass
(|>)
es im F # -Code so beliebt ist, weil es derSubject.Verb(Object)
Struktur von OO ähnelt . Da F # eine reibungslose Funktions- / OO-Integration anstrebt,Subject |> Verb Object
ist dies ein ziemlich reibungsloser Übergang für neue Funktionsprogrammierer.Persönlich denke ich auch gerne von links nach rechts, also benutze ich es
(|>)
in Haskell, aber ich glaube nicht, dass es viele andere Leute tun.quelle
Data.Sequence.|>
, aber es$>
sieht vernünftig aus, um Konflikte dort zu vermeiden. Ehrlich gesagt gibt es nur so viele gut aussehende Operatoren, dass ich sie nur|>
für beide verwenden und Konflikte von Fall zu Fall verwalten würde. (Auch ich wäre versucht, nur aliasData.Sequence.|>
alssnoc
)($)
und(|>)
sind Anwendung nicht Zusammensetzung. Die beiden sind verwandt (wie die Frage vermerkt), aber sie sind nicht gleich (Ihrfc
ist(Control.Arrow.>>>)
für Funktionen).|>
erinnert mich F #|
mehr als alles andere an UNIX .|>
F # ist, dass es nette Eigenschaften für IntelliSense in Visual Studio hat. Geben|>
Sie ein, und Sie erhalten eine Liste der Funktionen, die auf den Wert auf der linken Seite angewendet werden können, ähnlich wie beim Tippen.
nach einem Objekt.Ich denke, wir verwirren die Dinge. Haskells (
.
) entspricht F # (>>
). Nicht zu verwechseln mit F # 's (|>
), das nur eine invertierte Funktionsanwendung ist und Haskells ($
) ähnelt - umgekehrt:Ich glaube, Haskell-Programmierer verwenden
$
oft. Vielleicht nicht so oft wie F # -Programmierer|>
. Auf der anderen Seite verwenden einige F # -Typen>>
in lächerlichem Maße: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspxquelle
$
Operator von Haskell - umgekehrt, Sie können ihn auch leicht definieren als:a |> b = flip ($)
Dies entspricht der Pipeline von F #, z. B. können Sie dies dann tun[1..10] |> map f
.
) das gleiche wie (<<
), während (>>
) die umgekehrte Zusammensetzung ist. Das ist( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
vs( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
es gleichbedeutend ist mit>>
. Ich weiß nicht, ob F # hat,<<
aber das wäre das Äquivalent (wie in Elm).Wenn Sie F #
|>
in Haskell verwenden möchten, ist in Data.Function der&
Operator (seitbase 4.8.0.0
).quelle
&
über|>
? Ich denke, es|>
ist viel intuitiver und es erinnert mich auch an den Unix-Pipe-Operator.Komposition von links nach rechts in Haskell
Einige Leute verwenden auch in Haskell den Stil von links nach rechts (Nachrichtenübermittlung). Siehe zum Beispiel die mps- Bibliothek zu Hackage. Ein Beispiel:
Ich denke, dieser Stil sieht in manchen Situationen gut aus, ist aber schwieriger zu lesen (man muss die Bibliothek und alle ihre Operatoren kennen, die Neudefinition
(.)
ist auch störend).In Control.Category , einem Teil des Basispakets , gibt es auch Kompositionsoperatoren von links nach rechts sowie von rechts nach links . Vergleichen
>>>
und<<<
jeweils:Es gibt einen guten Grund, manchmal die Komposition von links nach rechts zu bevorzugen: Die Bewertungsreihenfolge folgt der Lesereihenfolge.
quelle
Ich habe gesehen
>>>
, wie man es benutztflip (.)
, und ich benutze es oft selbst, besonders für lange Ketten, die am besten von links nach rechts verstanden werden.>>>
ist eigentlich von Control.Arrow und funktioniert mit mehr als nur Funktionen.quelle
>>>
ist definiert inControl.Category
.Abgesehen von Stil und Kultur läuft dies darauf hinaus, das Sprachdesign für reinen oder unreinen Code zu optimieren.
Der
|>
Operator ist in F # vor allem deshalb üblich, weil er dazu beiträgt, zwei Einschränkungen zu verbergen, die bei überwiegend unreinem Code auftreten:Beachten Sie, dass die erstere Einschränkung in OCaml nicht existiert, da die Untertypisierung strukturell statt nominal ist, sodass der Strukturtyp im Verlauf der Typinferenz leicht durch Vereinheitlichung verfeinert werden kann.
Haskell geht einen anderen Kompromiss ein und konzentriert sich auf überwiegend reinen Code, bei dem diese Einschränkungen aufgehoben werden können.
quelle
Ich denke, F # 's Pipe Forward Operator (
|>
) sollte vs ( & ) in haskell sein.Wenn Sie den
&
Operator ( ) nicht mögen , können Sie ihn wie F # oder Elixir anpassen:Warum
infixl 1 |>
? Siehe das Dokument in Datenfunktion (&)(.)
(
.
) bedeutet Funktionszusammensetzung. Es bedeutet (fg) (x) = f (g (x)) in Mathe.es ist gleich
oder
(
$
) Operator ist auch in Data-Function ($) defind .(
.
) wird zum ErstellenHight Order Function
oder verwendetclosure in js
. Siehe Beispiel:Wow, weniger (Code) ist besser.
Vergleiche
|>
und.
Es ist der Unterschied zwischen
left —> right
undright —> left
. ⊙﹏⊙ |||Humanisierung
|>
und&
ist besser als.
weil
Wie funktioniert man in objektorientierter Sprache?
Bitte besuchen Sie http://reactivex.io/
IT-Unterstützung :
quelle
Dies ist mein erster Tag, an dem ich Haskell ausprobiert habe (nach Rust und F #), und ich konnte den Operator |> von F # definieren:
und es scheint zu funktionieren:
Ich wette, ein Haskell-Experte kann Ihnen eine noch bessere Lösung bieten.
quelle
x |> f = f x