2010-09-25 14 views
5

así que algo comoHaskell - ¿Currying? Necesita más explicación

addList :: [int] -> int 
addList = foldl1 (+) 

Por qué funciona esto? La parte de Currying. ¿Por qué no hay variable?

+0

A través de la recursión – Joren

+0

@Joren: En realidad, a través de funciones de orden superior. El OP preguntó acerca de la aplicación parcial, ahora acerca de los pliegues;) @Matt: La mayoría de los tutoriales decentes Haskell que he visto explicaron esto, aunque a veces no al instante. Si el tuyo no lo explica del todo, es posible que quieras cambiar. – delnan

+0

Lo entiendo cuando tiene coincidencia de patrones. Me gusta (((f 6) 7) 8) devuelve f 6 con un nuevo parámetro de 7 y lo mismo para 8. en este caso diga addList [1,2,3,4] se devuelve, pero simplemente no sé cómo fold1 obtiene esa lista. ¿Cómo sabe Haskell? Sé que tiene que ver con currying. – Matt

Respuesta

11

Si define una función como f x y = bla, esto es lo mismo que f x = \y -> bla, que es lo mismo que f = \x -> (\y -> bla). En otras palabras, f es una función que toma un argumento, x, y devuelve otra función que toma un argumento, y, y luego devuelve el resultado real. Esto se conoce como currying.

Análogamente cuando lo hace f x y, es lo mismo que (f x) y. Es decir. llama a la función f con el argumento x. Esto devuelve otra función, que aplica al argumento y.

En otras palabras, cuando lo hace addList xs = foldl1 (+) xs, primero está llamando a foldl1 (+) que luego devuelve otra función, que aplica a xs. Entonces, dado que la función devuelta por foldl1 (+) es en realidad la misma que addList, puede acortarla a addList = foldl1 (+).

2

La explicación de sepp2k es correcta, solo quiero señalar (juego de palabras) que esta aplicación de currying tiene un nombre: se llama "estilo sin puntos". Aquí hay una buena explicación, incluidos los pros y los contras: http://www.haskell.org/haskellwiki/Pointfree

5

Además del currying, como sepp2k señaló, aquí usamos el llamado eta reduction. Es una de las reglas de reducción del cálculo lambda, que es la base de Haskell. Dice que \x -> f x es equivalente a f cuando x no aparece en f.

Permite aplicarlo a su caso. Supongo que te sientes cómodo con una definición como addList xs = foldl1 (+) xs. Podemos reescribir esto como addList = \xs -> foldl1 (+) xs y ahora aplicando la regla de reducción eta obtenemos addList = foldl1 (+).

Esta regla se basa en la idea de que dos funciones son iguales si dan resultados iguales cuando se aplican a los mismos argumentos. Las dos funciones aquí son f y g = \x -> f x donde f : a -> b y queremos mostrar que para todos c : a, f c = g c. Para demostrarlo, tome un c : a arbitrario y aplíquelo al g: g c = (\x -> f x) c = f c, la última igualdad es por otra regla llamada reducción beta que dice que la aplicación de la función se evalúa por sustitución.

Cuestiones relacionadas