En F #, l'utilisation de l'opérateur pipe-forward,, |>
est assez courante. Cependant, dans Haskell, je n'ai jamais vu que des compositions de fonctions (.)
, utilisées. Je comprends qu'ils sont liés , mais y a-t-il une raison linguistique pour laquelle le pipe-forward n'est pas utilisé dans Haskell ou est-ce autre chose?
haskell
f#
functional-programming
composition
Ben Lings
la source
la source
&
c'est celle de Haskell|>
. Enterré profondément dans ce fil et m'a pris quelques jours à découvrir. Je l'utilise beaucoup, car vous lisez naturellement de gauche à droite pour suivre votre code.Réponses:
Je suis un peu spéculatif ...
Culture : Je pense que
|>
c'est un opérateur important dans la "culture" F #, et peut-être de la même manière.
pour Haskell. F # a un opérateur de composition de fonctions<<
mais je pense que la communauté F # a moins tendance à utiliser le style sans points que la communauté Haskell.Différences linguistiques : je ne connais pas assez les deux langues pour comparer, mais peut-être que les règles de généralisation des liaisons let sont suffisamment différentes pour affecter cela. Par exemple, je sais en F # parfois en écrivant
ne compilera pas, et vous avez besoin d'une conversion eta explicite:
pour le faire compiler. Cela éloigne également les gens du style sans points / compositionnel et vers le style de pipelining. De plus, l'inférence de type F # nécessite parfois un pipelining, de sorte qu'un type connu apparaît sur la gauche (voir ici ).
(Personnellement, je trouve le style sans points illisible, mais je suppose que chaque chose nouvelle / différente semble illisible jusqu'à ce que vous vous y habituiez.)
Je pense que les deux sont potentiellement viables dans l'une ou l'autre langue, et l'histoire / la culture / l'accident peuvent définir pourquoi chaque communauté s'est installée à un «attracteur» différent.
la source
.
et$
, donc les gens continuent de les utiliser.En F #
(|>)
est important en raison de la vérification de type de gauche à droite. Par exemple:généralement pas de vérification de type, car même si le type de
xs
est connu, le type de l'argumentx
du lambda n'est pas connu au moment où le vérificateur de type le voit, donc il ne sait pas comment le résoudrex.Value
.En revanche
fonctionnera très bien, car le type de
xs
mènera au type d'x
être connu.La vérification de type de gauche à droite est requise en raison de la résolution de nom impliquée dans des constructions comme
x.Value
. Simon Peyton Jones a écrit une proposition pour ajouter un type similaire de résolution de noms à Haskell, mais il suggère d'utiliser des contraintes locales pour savoir si un type prend en charge une opération particulière ou non. Ainsi, dans le premier échantillon, l'exigence quix
nécessite uneValue
propriété serait reportée jusqu'à ce qu'ellexs
soit vue et cette exigence pourrait être résolue. Cela complique cependant le système de types.la source
Plus de spéculations, cette fois du côté majoritairement Haskell ...
($)
est le flip de(|>)
, et son utilisation est assez courante lorsque vous ne pouvez pas écrire de code sans point. Donc, la principale raison qui(|>)
n'est pas utilisée dans Haskell est que sa place est déjà prise par($)
.De plus, en parlant d'un peu d'expérience F #, je pense que
(|>)
c'est si populaire dans le code F # parce qu'il ressemble à laSubject.Verb(Object)
structure d'OO. Puisque F # vise une intégration fonctionnelle / OO fluide,Subject |> Verb Object
c'est une transition assez fluide pour les nouveaux programmeurs fonctionnels.Personnellement, j'aime aussi penser de gauche à droite, donc j'utilise
(|>)
dans Haskell, mais je ne pense pas que beaucoup d'autres le font.la source
Data.Sequence.|>
, mais$>
semble raisonnable pour éviter les conflits là-bas. Honnêtement, il n'y a qu'un nombre limité d'opérateurs attrayants, donc je voudrais simplement utiliser|>
pour les deux et gérer les conflits au cas par cas. (Aussi je serais tenté de juste aliasData.Sequence.|>
commesnoc
)($)
et(|>)
sont l'application non la composition. Les deux sont liés (comme le note la question) mais ils ne sont pas identiques (votrefc
est(Control.Arrow.>>>)
pour les fonctions).|>
me rappellent en fait UNIX|
plus qu'autre chose.|>
F # est qu'il possède de bonnes propriétés pour IntelliSense dans Visual Studio. Tapez|>
, et vous obtenez une liste de fonctions qui peuvent être appliquées à la valeur de gauche, similaire à ce qui se passe lors de la saisie.
après un objet.Je pense que nous confondons les choses. Haskell's (
.
) est équivalent à F # 's (>>
). À ne pas confondre avec F # 's (|>
) qui est juste une application de fonction inversée et est comme Haskell ($
) - inversé:Je pense que les programmeurs Haskell utilisent
$
souvent. Peut-être pas aussi souvent que les programmeurs F # ont tendance à utiliser|>
. D'un autre côté, certains types F # utilisent>>
à un degré ridicule: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspxla source
$
opérateur de Haskell - inversé, vous pouvez aussi facilement le définir comme:a |> b = flip ($)
qui devient équivalent au pipeline de F #, par exemple vous pouvez le faire[1..10] |> map f
.
) est la même chose que (<<
), alors que (>>
) est la composition inverse. C'est( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
vs( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
soit équivalent à>>
. Je ne sais pas si F # l'a<<
mais ce serait l'équivalent (comme dans Elm).Si vous voulez utiliser des F #
|>
dans Haskell, alors Data.Function est l'&
opérateur (depuisbase 4.8.0.0
).la source
&
plus|>
? J'ai l'impression que|>
c'est beaucoup plus intuitif, et cela me rappelle également l'opérateur de tube Unix.&
très intuitif. Le code se lit presque correctement en anglais en prononçant simplement&
"et". Par exemple: se5 & factorial & show
lit à voix haute comme "prenez 5, puis prenez-en une factorielle et appliquez-y ensuite show".Composition de gauche à droite dans Haskell
Certaines personnes utilisent également le style de gauche à droite (passage de message) dans Haskell. Voir, par exemple, la bibliothèque mps sur Hackage. Un exemple:
Je pense que ce style a l'air bien dans certaines situations, mais il est plus difficile à lire (il faut connaître la bibliothèque et tous ses opérateurs, le redéfini
(.)
est aussi dérangeant).Il existe également des opérateurs de composition de gauche à droite et de droite à gauche dans Control.Category , qui fait partie du package de base. Comparez
>>>
et<<<
respectivement:Il y a une bonne raison de préférer parfois la composition de gauche à droite: l'ordre d'évaluation suit l'ordre de lecture.
la source
J'ai vu
>>>
être utilisé pourflip (.)
, et je l'utilise souvent moi-même, en particulier pour les longues chaînes qui sont mieux comprises de gauche à droite.>>>
est en fait de Control.Arrow, et fonctionne sur plus que de simples fonctions.la source
>>>
est défini dansControl.Category
.Outre le style et la culture, cela se résume à optimiser la conception du langage pour du code pur ou impur.
L'
|>
opérateur est courant dans F # en grande partie parce qu'il permet de masquer deux limitations qui apparaissent avec un code principalement impur:Notez que l'ancienne limitation n'existe pas dans OCaml car le sous-typage est structurel au lieu de nominal, de sorte que le type structurel est facilement affiné via l'unification au fur et à mesure que l'inférence de type progresse.
Haskell prend un compromis différent, choisissant de se concentrer sur du code principalement pur où ces limitations peuvent être levées.
la source
Je pense que l'opérateur pipe forward de F # (
|>
) devrait vs ( & ) dans haskell.Si vous n'aimez pas l'
&
opérateur ( ), vous pouvez le personnaliser comme F # ou Elixir:Pourquoi
infixl 1 |>
? Voir la doc dans Data-Function (&)(.)
(
.
) signifie composition de fonction. Cela signifie (fg) (x) = f (g (x)) en mathématiques.c'est égal
ou
L'
$
opérateur ( ) est également défini dans Data-Function ($) .(
.
) est utilisé pour créerHight Order Function
ouclosure in js
. Voir exemple:Wow, Less (code) c'est mieux.
Comparez
|>
et.
C'est la différence entre
left —> right
etright —> left
. ⊙﹏⊙ |||Humanisation
|>
et&
c'est mieux que.
car
Comment la programmation fonctionnelle en langage orienté objet?
veuillez visiter http://reactivex.io/
Support Informatique :
la source
C'est mon premier jour pour essayer Haskell (après Rust et F #), et j'ai pu définir l'opérateur |> de F #:
et cela semble fonctionner:
Je parie qu'un expert Haskell peut vous offrir une solution encore meilleure.
la source
x |> f = f x