haskell - ser - la funcion de relacion en los animales para niños
¿Cómo funciona la función de volteo? (4)
Haskell novato aquí. Estaba pasando por Learn you a haskell, y encontré esta definición de la función flip.
flip'' :: (a -> b -> c) -> (b -> a -> c)
flip'' f = g
where g x y = f y x
Lo que no entiendo es, ¿de dónde vienen x y y? Quiero decir, la firma me dice que flip'' es una función que toma una función (con dos parámetros) y devuelve una función (nuevamente, con dos parámetros).
Si estoy entendiendo esto bien, cuando escribo una función que va como
foo :: (a -> b) -> a -> b
foo f x = f x -- applies the function f on x
Pero entonces, en este caso estoy pasando el parámetro explícitamente [es decir, x ] y entonces puedo acceder a él en el cuerpo de la función. Entonces, ¿cómo es que la función flip'' puede acceder a los parámetros xey?
El Prelude , que está en el paquete base en hackage.haskell.org, se incluye con una importación implícita en cada archivo Haskell donde se encuentra la función de flip . En el lado derecho puede hacer clic en "fuente" y ver el código fuente para voltear .
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = f y x
La cláusula where permite definiciones locales, x=10 y="bla" . También puede definir funciones localmente con la misma sintaxis que usaría para el nivel superior. add xy = x + y
En la siguiente formulación equivalente hago la sustitución g = fyx
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = g
where
g = f y x
En este momento g no toma parámetros. Pero, ¿y si gab = fba g como gab = fba bien entonces tendríamos:
flip :: (a -> b -> c) -> b -> a -> c
flip f x y = g x y
where
g a b = f b a
No, podemos hacer una pequeña cancelación algebraica (si lo piensas como álgebra de la clase de matemáticas estarás bastante seguro). Enfocando en:
flip f x y = g x y
Cancele la y en cada lado para:
flip f x = g x
Ahora cancela la x:
flip f = g
y ahora para ponerlo de nuevo en la expresión completa:
flip :: (a -> b -> c) -> b -> a -> c
flip f = g
where
g a b = f b a
Como último paso estético, podemos hacer la sustitución a a x y b a y para recuperar la función a nombres de argumento:
flip :: (a -> b -> c) -> b -> a -> c
flip f = g
where
g x y = f y x
Como puede ver, esta definición de flip es un poco redonda y lo que comenzamos en el preludio es simple y es la definición que prefiero. Espero que ayude a explicar cómo funciona y cómo hacer una pequeña manipulación algebraica del código Haskell.
En pocas palabras, también puede definir funciones en un bloque where . Entonces las variables y son solo los parámetros formales de g , y es por eso que puedes acceder a él en gxy = fyx : gxy define los parámetros formales x e y , y fyx es la definición de lo que g hace. Finalmente, esa definición se devuelve desde flip f = g .
Encontremos el tipo de g .
Sabemos el tipo de volteo: (a -> b -> c) -> (b -> a -> c)
Por lo tanto, podemos deducir el tipo f : (a -> b -> c)
Tenemos esta definición para g
g x y = f y x
Del lado derecho deducimos que y :: a y x :: b .
Por lo tanto, g :: b -> a -> c
Tenga en cuenta que la definición podría reescribirse sin la cláusula ''where''.
flip'' f = g where g x y = f y x
-> flip'' f a b = g a b where g a b = f b a
-> flip'' f a b = f b a
flip'' no tiene acceso a x y y . Recibe un argumento f y evalúa la expresión g . No x o y a la vista.
Sin embargo, g es en sí mismo una función, definida con una ecuación auxiliar en la cláusula where de flip'' .
Puedes leer gxy = fyx exactamente como si fuera una ecuación de nivel superior como flip'' . Entonces g es una función de dos argumentos, x e y . Es g que tiene acceso a y , no flip'' . Los valores para esos argumentos no existen hasta que se aplica g , que no es hasta después de que flip'' haya devuelto la función g (si es que alguna vez).
Lo que es especial acerca de que g esté definido en la cláusula where de flip'' es que puede tener acceso a los argumentos de flip'' , que es cómo g se puede definir en términos de f .
Entonces cuando se invoca flip'' recibe una función f . Para cada invocación particular de flip'' , construye una nueva función g . g recibiría dos argumentos, x e y , cuando se llama, pero eso aún no ha sucedido. flip'' luego devuelve g como resultado.