[Práctico 2] [Ejercicio 7]

[Práctico 2] [Ejercicio 7]

de Eliana Rosselli Orrico -
Número de respuestas: 12

Buenas, 

Tengo una duda sobre el ejercicio 7 del práctico 2:

rara2 = zipWith (o) [length, sum] [drop 4, take 4]

No me queda claro si rara2 tiene algún parámetro de entrada? Por lo que entiendo, rara2 devuelve una lista de funciones, pero no me queda claro cómo aplicarla.

Gracias

En respuesta a Eliana Rosselli Orrico

Re: [Práctico 2] [Ejercicio 7]

de Marcos Viera - InCo -

No tiene ningún parámetro de entrada, rara2 es una lista de funciones. Entonces una posible aplicación de rara2 es:


head rara2 [1,2,3,4,5,6,7,8]


Cuánto da? Se les ocurre alguna otra aplicación?




En respuesta a Marcos Viera - InCo

Re: [Práctico 2] [Ejercicio 7]

de Santiago Correa Perini -

Sería aplicar length (.) drop 4 a la lista, no? Entonces el resultado sería:

4

En respuesta a Santiago Correa Perini

Re: [Práctico 2] [Ejercicio 7]

de Marcos Viera - InCo -

Perfecto. Cómo podemos hacer para aplicar la otra función de rara2? y qué daría si la aplicamos a la lista [1,2,3,4,5,6,7,8]?

En respuesta a Marcos Viera - InCo

Re: [Práctico 2] [Ejercicio 7]

de Santiago Correa Perini -

Sería:

> last rara2 [1,2,3,4,5,6,7,8]

con resultado 10

En respuesta a Santiago Correa Perini

Re: [Práctico 2] [Ejercicio 7]

de Marcos Viera - InCo -

Sólo te faltó un detalle: last retorna una lista (en este caso con un solo elemento), por lo que tenés que obtener su primer elemento.

> (head . last) rara2 [1,2,3,4,5,6,7,8]

El resultado está bien.

En respuesta a Marcos Viera - InCo

Re: [Práctico 2] [Ejercicio 7]

de Luis Ignacio Perdomo Berton -

Segun :t, last es del tipo [a] -> a, esto no significaria que last ya devuelve un elemento unico en lugar de una lista? Probe (last rara2) [1,2,3,4,5,6] y funciono.

En respuesta a Eliana Rosselli Orrico

Re: [Práctico 2] [Ejercicio 7]

de Luis Sierra -

es cierto, rara2 devuelve una lista de funciones. qué tipo tienen las funciones de esa lista? o sea, qué tipo tiene rara2?

supongamos que rara2 devuelve la lista [f1, f2]. cómo podrías hacer para obtener la lista [f1 arg, f2 arg]?

luis

En respuesta a Luis Sierra

Re: [Práctico 2] [Ejercicio 7]

de Santiago Correa Perini -

Teniendo en cuenta los tipos de length y sum sería:
rara2 :: [(Int -> [a] -> [a]) -> Int, Num b => (Int -> [b] -> [b]) -> b]
Y para obtener la lista [f1 arg, f2 arg] usas map:
[map x arg | x <- rara2]
Es correcto?

En respuesta a Santiago Correa Perini

Re: [Práctico 2] [Ejercicio 7]

de Marcos Viera - InCo -

> Teniendo en cuenta los tipos de length y sum sería:

> rara2 :: [(Int -> [a] -> [a]) -> Int, Num b => (Int -> [b] -> [b]) -> b]

La lista no puede almacenar elementos de tipos distintos. El tipo lista es [a], donde a es el tipo de sus elementos, así que el tipo que pusiste (con forma [a,b]) no es correcto.

Lo que hay que hacer es unificar los tipos de los elementos que compone y buscar el tipo más general que los contenga.

Los tipos de (length . drop 4) y (sum . take 4) no son los que pusiste, dado que no toman una función como parámetro, sino que toman una lista.

Fijate con estos datos podés resolver el tipo de rara2, sino la seguimos por acá.


> Y para obtener la lista [f1 arg, f2 arg] usas map:
> [map x arg | x <- rara2]

En realidad si usás la lista por comprensión no necesitás el map y si usas el map no necesitás la lista por comprensión.

Te animás a hacer alguna de las dos versiones? O ambas?

En respuesta a Marcos Viera - InCo

Re: [Práctico 2] [Ejercicio 7]

de Santiago Correa Perini -

Claro, quise reflejar que primero se aplica take y drop, pero cómo es take 4 y drop 4 sería entonces:

> rara2 :: Num a => [([a] -> Int)]

No se si incluir lo de Num a => (sum lo pide, length no, entonces para que contenga a ambos se incluye no?)
Dude en el tipo que devuelve porque sum devuelve a pero length Int, entonces Int restringe mas para contener a ambas no?

Bien. Por comprensión es sacar map de lo que puse:

> [ x arg | x <- rara2]

Pero map viendo su tipo, recibe una función y la aplica a todos los elementos de la lista, habría que ir aplicando uno por uno y unificando en una sola lista. Más fácil por comprensión, no se me ocurre ahora con map.

En respuesta a Santiago Correa Perini

Re: [Práctico 2] [Ejercicio 7]

de Marcos Viera - InCo -

>  Claro, quise reflejar que primero se aplica take y drop, pero cómo es take 4 y drop 4 sería entonces:

> >  rara2 :: Num a => [([a] -> Int)]

> No se si incluir lo de Num a => (sum lo pide, length no, entonces para que contenga a ambos se incluye no?)
> Dude en el tipo que devuelve porque sum devuelve a pero length Int, entonces Int restringe mas para contener a ambas no?

Veamos los tipos de ambas funciones (les pongo nombres distintos a las variables de tipo para no confundir):
length . drop 4 :: [a] -> Int
sum . take 4 :: Num b => [b] -> b

De esto podemos deducir que

b = Int

(que cumple con la condición de ser instancia de Num)

y

a = b

Entonces el tipo es:

[[Int] -> Int]


> Bien. Por comprensión es sacar map de lo que puse:

> > [ x arg | x <- rara2]

> Pero map viendo su tipo, recibe una función y la aplica a todos los elementos de la lista, habría que ir aplicando uno por uno y unificando en una sola lista. Más fácil por comprensión, 

> no se me ocurre ahora con map.


La definición por comprensión que diste está perfecta, aunque yo a la variable la llamaría 'f' en lugar de 'x' :-)


En el caso del map, la función que tendría que pasarle es la que aplica la función que tengo en la lista al argumento arg. 

Si la implementamos como una función anónima nos quedaría:

map (\f -> f arg)  rara2

o lo que es lo mismo, aplicando flip y el operador de aplicación:

map (flip ($) arg)  rara2

o lo que es lo mismo, usando secciones:

map ($ arg) rara2