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]
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.