Hola,
Permitime cambiarle los nombres a los parámetros, así queda menos entreverado:
f4 f x y = head [f x, f4 f (tail x) y]
si quiero asignar el tipo f4 :: (a -> b) -> a -> [a] -> b
entonces, entre otras cosas estoy diciendo que el parámetro x tiene tipo a, que es polimórfico. O sea que debería de poder pasar cualquier cosa como x.
En cambio en la definición de la función hago (tail x), lo que indicaría que ese parámetro tiene que ser sí o sí una lista. En conclusión, el tipo es demasiado polimórfico para su implementación.
Las expresiones lambda simplemente nos permiten definir funciones a nivel de expresión, sin necesidad de asignarles un nombre. No tienen ningún tipo en especial.
Por ejemplo, la f1 del ejercicio es equivalente a:
f1 f a = f1 foo a b
where foo x = f a
saludos
Permitime cambiarle los nombres a los parámetros, así queda menos entreverado:
f4 f x y = head [f x, f4 f (tail x) y]
si quiero asignar el tipo f4 :: (a -> b) -> a -> [a] -> b
entonces, entre otras cosas estoy diciendo que el parámetro x tiene tipo a, que es polimórfico. O sea que debería de poder pasar cualquier cosa como x.
En cambio en la definición de la función hago (tail x), lo que indicaría que ese parámetro tiene que ser sí o sí una lista. En conclusión, el tipo es demasiado polimórfico para su implementación.
Las expresiones lambda simplemente nos permiten definir funciones a nivel de expresión, sin necesidad de asignarles un nombre. No tienen ningún tipo en especial.
Por ejemplo, la f1 del ejercicio es equivalente a:
f1 f a = f1 foo a b
where foo x = f a
saludos