[Practico 2] [Ejercicio 8]

[Practico 2] [Ejercicio 8]

de Sebastian Guerrero Font -
Número de respuestas: 1

Hola, tenia una duda de este ejercicio. Si tengo que pensar el tipo de twice me imagino que seria algo como:

twice :: (a -> a) -> a -> a

Y de hecho el ghci me dice eso mismo con el :t.
Entonces hacer twice tail funcionaria ya que tail :: [a] -> [a] encaja con el tipo de la funcion, pero no de head ya que head :: [a] -> a. 

La duda que me queda es que se pueden definir funciones que se pueden componer normalmente pero fallarian al pasarselas a twice.
Ejemplo:

toList :: a -> [a]
toList x = [x]   

Se pueden componer con si misma (toList.toList :: a -> [[a]]) pero no se las puedo pasar a twice. Entiendo que no encaja con el tipado de twice, ahora, hay algo que me sono raro. Eso de que el reemplazar una funcion por su implementacion y que haya comportamientos distintos (que uno compila y otro no) me llamo la atencion. Lo pongo aca por si hay algo que se me esta pasando por alto.

En respuesta a Sebastian Guerrero Font

Re: [Practico 2] [Ejercicio 8]

de Juan Pablo García Garland -

Hola Sebastian.

Es interesante lo que planteás. twice toList no tipa porque toList no tiene un tipo de la forma a -> a. La expresión toList . toList está bien tipada. Parece paradójico.

Lo que ocurre es que para que toList . toList esté bien tipada las ocurrencias de toList tienen que tener tipos distintos..

Al usar twice en Haskell "fijamos" la f que aplicamos dos veces (incluido su tipo). Esto tiene que ver con la naturaleza del polimorfismo tal como lo implementa Haskell.