recursive maximum guards functions else haskell syntax operators

haskell - maximum - ¿Cuándo debería usar $(y siempre se puede reemplazar con paréntesis)?



maximum in haskell (5)

Según lo que estoy leyendo, $ se describe como "aplica una función a sus argumentos". Sin embargo, no parece funcionar bastante como (apply ...) en Lisp, porque es un operador binario, así que realmente lo único que parece es que ayuda a evitar paréntesis a veces, como foo $ bar quux lugar de foo (bar quux) . ¿Lo estoy entendiendo bien? ¿La última forma se considera "mal estilo"?


En su mayoría lo entiendes bien, es decir, aproximadamente el 99% del uso de $ es para ayudar a evitar paréntesis, y sí, parece ser preferible a paréntesis en la mayoría de los casos.

Nota, sin embargo:

> :t ($) ($) :: (a -> b) -> a -> b

Es decir, $ es una función; como tal, se puede pasar a funciones, compuestas con, y cualquier otra cosa que quieras hacer con él. Creo que lo he visto usado por personas que antes usaban combinadores.


La documentación de ($) responde su pregunta. Lamentablemente, no figura en la documentación generada automáticamente del Preludio .

Sin embargo, se enumera en el código fuente que puede encontrar aquí:

http://darcs.haskell.org/packages/base/Prelude.hs

Sin embargo, este módulo no define ($) directamente. El siguiente, que es importado por el primero, hace:

http://darcs.haskell.org/packages/base/GHC/Base.lhs

Incluí el código relevante a continuación:

infixr 0 $ ... -- | Application operator. This operator is redundant, since ordinary -- application @(f x)@ means the same as @(f ''$'' x)@. However, ''$'' has -- low, right-associative binding precedence, so it sometimes allows -- parentheses to be omitted; for example: -- -- > f $ g $ h x = f (g (h x)) -- -- It is also useful in higher-order situations, such as @''map'' (''$'' 0) xs@, -- or @''Data.List.zipWith'' (''$'') fs xs@. {-# INLINE ($) #-} ($) :: (a -> b) -> a -> b f $ x = f x


Muchas buenas respuestas arriba, pero una omisión:

$ no siempre se puede reemplazar por paréntesis

Pero cualquier aplicación de $ se puede eliminar mediante el uso de paréntesis , y cualquier uso de ($) se puede reemplazar por id , ya que $ es una especialización de la función de identidad . Los usos de (f$) se pueden reemplazar por f , pero un uso como ($x) (tomar una función como argumento y aplicarlo a x ) no tiene ningún reemplazo obvio que yo vea.


$ se prefiere entre paréntesis cuando la distancia entre los paréntesis de apertura y cierre sería superior a la buena legibilidad, o si tiene varias capas de paréntesis anidados.

Por ejemplo

i (h (g (f x)))

puede ser reescrito

i $ h $ g $ f x

En otras palabras, representa la aplicación de función asociativa derecha. Esto es útil porque la aplicación de función ordinaria se asocia a la izquierda, es decir, la siguiente

i h g f x

... puede ser reescrito de la siguiente manera

(((i h) g) f) x

Otros usos útiles de la función ($) incluyen comprimir una lista con ella:

zipWith ($) fs xs

Esto aplica cada función en una lista de funciones fs a un argumento correspondiente en la lista xs , y recopila los resultados en una lista. Contraste con la sequence fs x que aplica una lista de funciones fs a un único argumento x y recopila los resultados; y fs <*> xs que aplica cada función en la lista fs a cada elemento de la lista xs .


Si veo tu pregunta y las respuestas aquí, Apocalisp y tú tienen razón:

  • $ se prefiere entre paréntesis en ciertas circunstancias (ver su respuesta)
  • foo (bar quux) ciertamente no es un mal estilo!

Además, por favor verifique la diferencia entre. (punto) y $ (signo de dólar) , otra pregunta SO muy relacionada con la suya.