Question

En F #, l'utilisation du l'opérateur de tuyau avant, |>, est assez commun. Cependant, dans Haskell, je ne l'ai composition fonction jamais vu, (.), utilisé. Je comprends qu'ils sont connexes, mais est il une raison linguistique tuyau avant ne soit pas utilisé dans Haskell ou est-ce autre chose?

Était-ce utile?

La solution

Je suis d'être un peu spéculatif ...

Culture : Je pense que |> est un opérateur important dans le F # "culture", et peut-être de même avec . pour Haskell. F # a un opérateur de composition fonction << mais je pense que la communauté F # a tendance à utiliser le style des points sans moins que la communauté Haskell.

Les différences linguistiques : Je ne sais pas assez sur les deux langues à comparer, mais peut-être les règles pour les liaisons let-généralisant sont suffisamment différents pour affecter cela. Par exemple, je sais que dans F # écrit parfois

let f = exp

ne compilera pas, et vous avez besoin eta conversion explicite:

let f x = (exp) x   // or x |> exp

pour faire la compilation. Cette aide aussi les gens loin de style des points libres / composition, et vers le style de pipelining. En outre, F # inférence de type demande parfois pipelining, de sorte qu'un type connu apparaît sur la gauche (voir

Autres conseils

Plus la spéculation, cette fois du côté principalement Haskell ...

($) est le revers de (|>), et son utilisation est assez fréquent quand vous ne pouvez pas écrire du code sans le point. Ainsi, la principale raison pour laquelle (|>) pas utilisé dans Haskell est que sa place est déjà prise par ($).

En outre, en parlant d'un peu d'expérience F #, je pense que (|>) est si populaire en F # code car il ressemble à la structure de Subject.Verb(Object) de OO. Puisque F # vise une intégration en douceur fonctionnelle / OO, Subject |> Verb Object est une transition assez lisse pour les nouveaux programmeurs fonctionnels.

Personnellement, j'aime penser trop à droite à gauche, donc j'utilise (|>) en Haskell, mais je ne pense pas que beaucoup d'autres personnes.

Si vous voulez utiliser |> dans Haskell de F # puis dans Data.Function est l'opérateur & (depuis base 4.8.0.0).

Composition de gauche à droite dans Haskell

Certaines personnes utilisent le style de gauche à droite (passage de messages) dans Haskell aussi. Voir, par exemple, bibliothèque de mps sur Hackage. Un exemple:

euler_1 = ( [3,6..999] ++ [5,10..999] ).unique.sum

Je pense que ce style a l'air bien dans certaines situations, mais il est plus difficile à lire (on a besoin de connaître la bibliothèque et tous ses opérateurs, l'(.) redéfini est inquiétant aussi).

Il y a aussi de gauche à droite-ainsi que les opérateurs de composition de droite à gauche dans Control.Category , une partie du paquet de base. Comparer respectivement >>> et <<<:

ghci> :m + Control.Category
ghci> let f = (+2) ; g = (*3) in map ($1) [f >>> g, f <<< g]
[9,5]

Il y a une bonne raison de préférer la composition à droite à gauche parfois. Ordre d'évaluation suit l'ordre de lecture

Je l'ai vu >>> utilisé pour flip (.), et je l'utilise souvent moi-même, en particulier pour les longues chaînes qui sont plus faciles à comprendre de gauche à droite.

>>> est en fait de Control.Arrow, et travaille sur plus que des fonctions.

En plus de style et de la culture, cela se résume à l'optimisation de la conception de la langue soit pour le code pur ou impur.

L'opérateur |> est commun dans F # en grande partie parce qu'il aide à cacher deux limitations qui apparaissent avec le code majoritairement impur:

  • De gauche à droite inférence de type sans sous-types de structure.
  • La restriction de valeur.

Notez que la première limitation n'existe pas en OCaml, car le sous-typage est plutôt structurel de la valeur nominale, de sorte que le type de construction est facilement raffiné par l'unification comme l'inférence de type progresse.

Haskell prend un autre compromis, le choix de se concentrer sur le code essentiellement pur où ces limitations peuvent être levées.

Je pense que F tuyau d '# opérateur avant ( |> ) devrait vs ( ) haskell.

// pipe operator example in haskell

factorial :: (Eq a, Num a) =>  a -> a
factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)

// terminal
ghic >> 5 & factorial & show

Si vous ne aimez pas ( & ) opérateur, vous pouvez personnaliser comme F # ou Elixir:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 1 |>
ghci>> 5 |> factorial |> show

Pourquoi infixl 1 |>? Voir la doc dans données-fonction (&)

  

infixl = infix + associativité gauche

     

infixr = infix + droit associativité


(.)

( . ) signifie la composition de fonctions. Cela signifie (fg) (x) = f (g (x)) en mathématiques.

foo = negate . (*3)
// ouput -3
ghci>> foo 1
// ouput -15
ghci>> foo 5

il est égal à

// (1)
foo x = negate (x * 3) 

ou

// (2)
foo x = negate $ x * 3 

( $ ) est également opérateur defind en données-fonction ($) .

( . ) est utilisé pour créer Hight Order Function ou closure in js. Voir par exemple:


// (1) use lamda expression to create a Hight Order Function
ghci> map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]


// (2) use . operator to create a Hight Order Function
ghci> map (negate . abs) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]

Wow, moins (code) est mieux.


Comparez |> et .

ghci> 5 |> factorial |> show

// equals

ghci> (show . factorial) 5 

// equals

ghci> show . factorial $ 5 

Il est la différence entre left —> right et right —> left. ⊙﹏⊙ |||

Humanisation

|> et & est mieux que .

parce que

ghci> sum (replicate 5 (max 6.7 8.9))

// equals

ghci> 8.9 & max 6.7 & replicate 5 & sum

// equals

ghci> 8.9 |> max 6.7 |> replicate 5 |> sum

// equals

ghci> (sum . replicate 5 . max 6.7) 8.9

// equals

ghci> sum . replicate 5 . max 6.7 $ 8.9

Comment la programmation fonctionnelle dans un langage orienté objet?

http://reactivex.io/

Support:

  • Java: RxJava
  • JavaScript: RxJS
  • C #: Rx.NET
  • C # (Unité): UniRx
  • Scala: RxScala
  • Clojure: RxClojure
  • C ++: RxCpp
  • Lua: RxLua
  • Ruby: Rx.rb
  • Python: RxPY
  • Go: RxGo
  • Groovy: RxGroovy
  • JRuby: RxJRuby
  • Kotlin: RxKotlin
  • Swift: RxSwift
  • PHP: RxPHP
  • Elixir: reaxive
  • Dart: RxDart

Ceci est mon premier jour pour essayer Haskell (après la rouille et F #), et je suis en mesure de définir F # 's |> opérateur:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 0 |>

et il semble fonctionner:

factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)

main =     
    5 |> factorial |> print

Je parie un expert Haskell peut vous donner une solution encore mieux.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top