Buenas,
Haciendo varios parciales he visto que usan bastante seguido la notacion (f a), por ejemplo cosas como (<2), (+1) o (div 2) pero no me queda claro como traducirlo a algo no currificado. Me refiero a que por ejemplo (<2) 3 se traduce a 3 < 2 pero (div 2) 4 se traduce a 2 div 4. La diferencia ahi es que cuando se tiene (f a) b, a y b parecen ir para lados distintos del operador dependiendo de cual sea el operador. Supongo que sigue algun patron pero no me estoy dando cuenta ¿Cual es?
Muchas gracias
Dudas sobre interpretacion de funciones currificadas
Número de respuestas: 3
En respuesta a Tomas Pasacual Sexenian Lopez
Re: Dudas sobre interpretacion de funciones currificadas
de Alberto Pardo -
Hola Tomás,
El caso de div (o mismo mod) puede confundir un poco porque es muy usual que se lo use en forma infija. En Haskell si escribimos simplemente div eso significa la función prefija div :: Int -> Int -> Int (digamos Int para fijar ideas, div tiene un tipo mas general). O sea, escribimos div 2 3 para denotar la división entera de 2 entre 3. Alternativamente pdemos escribir (div 2) 3 que significa lo mismo. Eso pasa con toda función currificada f :: a -> b -> c. Es lo mismo escribir f x y que (f x) y. Al decir (f x) eso retorna una función de tipo b -> c, que luego, al aplicarla a y :: c retorna un valor de tipo c.
Volviendo a la división, dado que es una función que tiene 2 parámetros puedo escribirla en forma "infija" si encierro el nombre con back-quotes (comillas para atrás). Entonces puedo escribir div 2 3 como 2 `div` 3. Eso puedo hacer con cualquier función en dos parámetros. Volviendo a f :: a -> b -> c, f x y lo puedo escribir como x `f` y. A partir de eso puedo jugar a armar secciones con la función en notación infija. Por ejemplo, puedo escribir (`div` 3) para hablar de la función que toma un entero y lo divide entre 3 (o sea, la función \x -> x div 3) o (2 `div`) para hablar de la función que toma un entero y divide 2 entre ese número (o sea, \x -> 2 div x).
No es correcto escribir 2 div 3, sino que hay que escribir 2 `div` 3.
Espero haber aclarado la duda.
Saludos,
Alberto.
El caso de div (o mismo mod) puede confundir un poco porque es muy usual que se lo use en forma infija. En Haskell si escribimos simplemente div eso significa la función prefija div :: Int -> Int -> Int (digamos Int para fijar ideas, div tiene un tipo mas general). O sea, escribimos div 2 3 para denotar la división entera de 2 entre 3. Alternativamente pdemos escribir (div 2) 3 que significa lo mismo. Eso pasa con toda función currificada f :: a -> b -> c. Es lo mismo escribir f x y que (f x) y. Al decir (f x) eso retorna una función de tipo b -> c, que luego, al aplicarla a y :: c retorna un valor de tipo c.
Volviendo a la división, dado que es una función que tiene 2 parámetros puedo escribirla en forma "infija" si encierro el nombre con back-quotes (comillas para atrás). Entonces puedo escribir div 2 3 como 2 `div` 3. Eso puedo hacer con cualquier función en dos parámetros. Volviendo a f :: a -> b -> c, f x y lo puedo escribir como x `f` y. A partir de eso puedo jugar a armar secciones con la función en notación infija. Por ejemplo, puedo escribir (`div` 3) para hablar de la función que toma un entero y lo divide entre 3 (o sea, la función \x -> x div 3) o (2 `div`) para hablar de la función que toma un entero y divide 2 entre ese número (o sea, \x -> 2 div x).
No es correcto escribir 2 div 3, sino que hay que escribir 2 `div` 3.
Espero haber aclarado la duda.
Saludos,
Alberto.
En respuesta a Alberto Pardo
Re: Dudas sobre interpretacion de funciones currificadas
Entendi lo de los backquotes. Simplificando un poco puedo decir que div 2 3 = (`div` 3) 2 = dividir 2 entre 3.
Pero volviendo al ejemplo que puse yo (<2) 3 deberia traducirse como 2 < 3 pues entiendo que la funcion < tambien es una funcion que toma 2 parametros y no la estoy encerrando entre backquotes, sin embargo (<2) 3 se traduce a 3 < 2 ¿Por que es esto? Mi duda, en general, es: Dada una funcion f que toma dos parametros ¿Como hago la traduccion de notacion prefija a notacion infija? Osea, como se que parametro va a la izquierda y cual va a la derecha del operador
Pero volviendo al ejemplo que puse yo (<2) 3 deberia traducirse como 2 < 3 pues entiendo que la funcion < tambien es una funcion que toma 2 parametros y no la estoy encerrando entre backquotes, sin embargo (<2) 3 se traduce a 3 < 2 ¿Por que es esto? Mi duda, en general, es: Dada una funcion f que toma dos parametros ¿Como hago la traduccion de notacion prefija a notacion infija? Osea, como se que parametro va a la izquierda y cual va a la derecha del operador
En respuesta a Tomas Pasacual Sexenian Lopez
Re: Dudas sobre interpretacion de funciones currificadas
de Alberto Pardo -
Hola,
En el caso de los operadores binarios infijos, como <, <=, +, *, ++ y otros no es necesario usar backquotes, ellos son por definición infijos. Por lo tanto podemos escribo 2 < 3, 2 + 3, etc. Luego podemos usarlos para definir secciones como (2+), (+3), (2>), (>0), etc. Los operadores infijos los podemos usar como funciones prefijas currificadas escribiéndolos entre paréntesis. Por ejemplo (>) :: Ord a => a -> a -> Bool.
Al definir una sección saturamos uno de sus parámetros. O sea, escribimos (<2) o (+1). El resultado de hacer eso es una función en un argumento. En el caso de (<2) estamos saturando las segunda posición del < y por lo tanto cuando aplicamos el argumento ocupará la primera posición (la no saturada). Por ejemplo, (<2) 3 da como resultado 3 < 2. Esto es porque escribir (<2) es equivalente a \x -> x < 2.
Dada una función f :: a -> b -> c, al escribirla como infija (`f`) sus dos parámetros posicionales van a respetar el orden de los parámetros de la función f, o sea, el izquierdo será de tipo a y el derecho de tipo b. Puedo entonces armar secciones como (x `f`) o (`f` y).
Saludos,
Alberto.