En F #, el uso del operador pipe-forward`` |>
es bastante común. Sin embargo, en Haskell solo he visto cómo (.)
se usa la composición de funciones,. Entiendo que están relacionados , pero ¿hay alguna razón lingüística por la que no se use pipe-forward en Haskell o es algo más?
haskell
f#
functional-programming
composition
Ben Lings
fuente
fuente
&
es de Haskell|>
. Enterrado en lo profundo de este hilo y me tomó unos días descubrirlo. Lo uso mucho, porque naturalmente lees de izquierda a derecha para seguir tu código.Respuestas:
Estoy siendo un poco especulativo ...
Cultura : Creo que
|>
es un operador importante en la "cultura" de F #, y tal vez de manera similar con.
Haskell. F # tiene un operador de composición de funciones,<<
pero creo que la comunidad F # tiende a usar menos el estilo sin puntos que la comunidad Haskell.Diferencias de idioma : no sé lo suficiente sobre ambos idiomas para comparar, pero quizás las reglas para generalizar los enlaces let son lo suficientemente diferentes como para afectar esto. Por ejemplo, sé que en F # a veces escribo
no se compilará, y necesita una conversión eta explícita:
para que se compile. Esto también aleja a la gente del estilo libre de puntos / compositivo y hacia el estilo de canalización. Además, la inferencia de tipo F # a veces exige canalización, por lo que un tipo conocido aparece a la izquierda (ver aquí ).
(Personalmente, encuentro ilegible el estilo sin puntos, pero supongo que cada cosa nueva / diferente parece ilegible hasta que te acostumbras).
Creo que ambos son potencialmente viables en cualquier idioma, y la historia / cultura / accidente puede definir por qué cada comunidad se estableció en un "atractor" diferente.
fuente
.
y$
, por lo que la gente continúa usándolos.En F #
(|>)
es importante debido a la verificación de tipo de izquierda a derecha. Por ejemplo:generalmente no se verificará el tipo, porque incluso si
xs
se conoce el tipo de, el tipo de argumentox
de la lambda no se conoce en el momento en que el verificador de tipos lo ve, por lo que no sabe cómo resolverlox.Value
.A diferencia de
funcionará bien, porque el tipo de
xs
conducirá al tipo dex
ser conocido.Se requiere la verificación de tipo de izquierda a derecha debido a la resolución de nombres involucrada en construcciones como
x.Value
. Simon Peyton Jones ha escrito una propuesta para agregar un tipo similar de resolución de nombres a Haskell, pero sugiere usar restricciones locales para rastrear si un tipo admite una operación en particular o no. Entonces, en la primera muestra, el requisito quex
necesita unaValue
propiedad se trasladaría hasta quexs
se vea y este requisito se pueda resolver. Sin embargo, esto complica el sistema de tipos.fuente
Más especulaciones, esta vez del lado predominantemente de Haskell ...
($)
es el cambio(|>)
, y su uso es bastante común cuando no se puede escribir código sin puntos. Entonces, la razón principal por la que(|>)
no se usa en Haskell es que su lugar ya está ocupado($)
.Además, hablando de un poco de experiencia en F #, creo que
(|>)
es muy popular en el código F # porque se parece a laSubject.Verb(Object)
estructura de OO. Dado que F # tiene como objetivo una integración funcional / OO sin problemas,Subject |> Verb Object
es una transición bastante suave para los nuevos programadores funcionales.Personalmente, también me gusta pensar de izquierda a derecha, así que lo uso
(|>)
en Haskell, pero no creo que muchas otras personas lo hagan.fuente
Data.Sequence.|>
, pero$>
parece razonable para evitar conflictos allí. Honestamente, solo hay una cantidad limitada de operadores atractivos, por lo que solo usaría|>
para ambos y manejaría los conflictos caso por caso. (También estaría tentado a usar un aliasData.Sequence.|>
comosnoc
)($)
y(|>)
son aplicación, no composición. Los dos están relacionados (como señala la pregunta) pero no son lo mismo (el suyofc
es(Control.Arrow.>>>)
para funciones).|>
me recuerda|
más a UNIX que a cualquier otra cosa.|>
F # es que tiene buenas propiedades para IntelliSense en Visual Studio. Escriba|>
y obtendrá una lista de funciones que se pueden aplicar al valor de la izquierda, similar a lo que sucede al escribir.
después de un objeto.Creo que estamos confundiendo las cosas. (
.
) De Haskell es equivalente a ( ) de F #>>
. No confundir con F # 's (|>
) que es solo una aplicación de función invertida y es como Haskell's ($
) - invertida:Creo que los programadores de Haskell lo usan con
$
frecuencia. Quizás no tan a menudo como los programadores de F # tienden a usar|>
. Por otro lado, algunos tipos de F # usan>>
en un grado ridículo: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspxfuente
$
operador de Haskell : al revés, también puede definirlo fácilmente como:a |> b = flip ($)
que se convierte en equivalente a la tubería de F #, por ejemplo, puede hacerlo[1..10] |> map f
.
) es lo mismo que (<<
), mientras que (>>
) es la composición inversa. Eso es( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
vs( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
sea equivalente a>>
. No sé si F # lo ha hecho,<<
pero ese sería el equivalente (como en Elm).Si desea usar F #
|>
en Haskell, entonces en Data.Function es el&
operador (desdebase 4.8.0.0
).fuente
&
más|>
? Siento que|>
es mucho más intuitivo y también me recuerda al operador de tubería de Unix.Composición de izquierda a derecha en Haskell
Algunas personas también usan el estilo de izquierda a derecha (paso de mensajes) en Haskell. Consulte, por ejemplo, la biblioteca mps en Hackage. Un ejemplo:
Creo que este estilo se ve bien en algunas situaciones, pero es más difícil de leer (es necesario conocer la biblioteca y todos sus operadores, el redefinido también
(.)
es perturbador).También hay operadores de composición de izquierda a derecha y de derecha a izquierda en Control.Category , parte del paquete base. Compare
>>>
y<<<
respectivamente:Hay una buena razón para preferir la composición de izquierda a derecha a veces: el orden de evaluación sigue el orden de lectura.
fuente
He visto
>>>
que me utilizanflip (.)
, y a menudo lo uso yo mismo, especialmente para cadenas largas que se entienden mejor de izquierda a derecha.>>>
es en realidad de Control.Arrow y funciona en más que solo funciones.fuente
>>>
se define enControl.Category
.Aparte del estilo y la cultura, esto se reduce a optimizar el diseño del lenguaje para código puro o impuro.
El
|>
operador es común en F # en gran parte porque ayuda a ocultar dos limitaciones que aparecen con código predominantemente impuro:Tenga en cuenta que la primera limitación no existe en OCaml porque el subtipo es estructural en lugar de nominal, por lo que el tipo estructural se refina fácilmente mediante unificación a medida que avanza la inferencia de tipos.
Haskell toma una compensación diferente, eligiendo enfocarse en un código predominantemente puro donde estas limitaciones se pueden eliminar.
fuente
Creo que el operador de avance de tubería de F # (
|>
) debería frente a ( & ) en haskell.Si no le gusta el
&
operador ( ), puede personalizarlo como F # o Elixir:¿Por qué
infixl 1 |>
? Ver el documento en función de datos (&)(.)
(
.
) significa composición de funciones. Significa (fg) (x) = f (g (x)) en matemáticas.es igual
o
El
$
operador ( ) también se define en la función de datos ($) .(
.
) se utiliza para crearHight Order Function
oclosure in js
. Ver ejemplo:Vaya, Menos (código) es mejor.
Comparar
|>
y.
Es la diferencia entre
left —> right
yright —> left
. ⊙﹏⊙ |||Humanización
|>
y&
es mejor que.
porque
¿Cómo programar funcional en lenguaje orientado a objetos?
visite http://reactivex.io/
Soporte de TI :
fuente
Este es mi primer día para probar Haskell (después de Rust y F #), y pude definir el operador |> de F #:
Y parece funcionar:
Apuesto a que un experto en Haskell puede ofrecerle una solución aún mejor.
fuente
x |> f = f x