2010-05-14 19 views
14

trato de desarrollar una función promedio simple en Haskell. Esto parece funcionar:Haskell operador punto

lst = [1, 3] 

x = fromIntegral (sum lst) 
y = fromIntegral(length lst) 

z = x/y 

Pero por qué no hace el trabajo siguiente versión?

lst = [1, 3] 

x = fromIntegral.sum lst 
y = fromIntegral.length lst 

z = x/y 
+1

Y ya que estás calculando la media, por favor, lea http://stackoverflow.com/questions/2376981/haskell-types-frustrating-a-simple-average-function/2380437 # 2380437. – kennytm

Respuesta

16

Te estás tropezar por las reglas de prioridad de Haskell para los operadores, que son confusas.

Cuando se escribe

x = fromIntegral.sum lst 

Haskell ve que como el mismo que:

x = fromIntegral.(sum lst) 

Lo que significa que escribir era:

x = (fromIntegral.sum) lst 
+8

Eso es verdad. Pero creo que escribir operadores sin espacios a su alrededor a veces conduce a malentendidos (es decir, se parece a la construcción de acceso de miembros en muchos lenguajes centrados en OOP). '(fromIntegral. sum)' puede causar preguntas, pero no malas interpretaciones. – ony

+1

Para ser sinceros, lo que está confundiendo aquí no es reglas de precedencia de Haskell en sí mismos (que son fáciles de estado) pero la desconcertante (a) el principiante variedad de operadores, cada uno con su propia prioridad, que se define en el preludio. – sigfpe

17

. (composición) tiene una precedencia más baja que la aplicación de funciones, por lo

fromIntegral.sum lst 

se interpreta como

fromIntegral . (sum lst) 

que está mal desde sum lst no es una función.

10

Sólo quería añadir "$ al rescate! ":

x = fromIntegral $ sum lst 
y = fromIntegral $ length lst 

Tiene la prioridad más baja y que está ahí para evitar demasiados niveles de paréntesis. Tenga en cuenta que a diferencia de (.), No hace la composición de la función, evalúa el argumento a la derecha y lo pasa a la función de la izquierda. El tipo dice todo:

($) :: (a -> b) -> a -> b 
(.) :: (b -> c) -> (a -> b) -> a -> c 
+1

Y también podría escribir 'x = fromIntegral. sum $ lst' que está aún más cerca de lo que originalmente intentó el OP. – yatima2975

+0

No es * bastante * exacto decir que evalúa el argumento a la derecha. La evaluación todavía es floja. Para evaluar el argumento, querría '$!' En su lugar. – Chuck

+0

Aunque esta solución funciona, no creo que sea la respuesta correcta aquí. Para mí, parece que OP está confundido acerca de la precedencia del operador. Entonces la respuesta es indicar la precedencia apropiada y señalar que los paréntesis ayudan aquí. No introducir otro operador. – Martijn

Cuestiones relacionadas