Antecedentes: estoy investigando la recursión anónima, y estoy asumiendo el desafío de implementar el preludio sin utilizar ninguna recursividad con nombre solo para ayudarlo a que todo quede bien en mi mente. Aún no llegué, y en el camino me encontré con algo que no está relacionado pero que sigue siendo interesante.Funciones equivalentes que producen diferentes resultados de intérprete
map1 = \f -> \x -> if (tail x) == []
then [f (head x)]
else f (head x) : (map1 f (tail x))
map2 f x = if (tail x) == []
then [f (head x)]
else f (head x) : (map2 f (tail x))
map3 f (x:xs) = if xs == [] then [f x] else f x : (map3 f xs)
map4 f (x:[]) = [f x]
map4 f (x:xs) = f x : map4 f xs
GHC se queja de la primera, está muy bien con la segunda y la tercera y cuarta son allí sólo para mostrar cómo podrían ser implementadas de manera diferente.
*Main> map1 (*2) [1..10]
<interactive>:1:15:
No instance for (Num())
arising from the literal `10'
Possible fix: add an instance declaration for (Num())
In the expression: 10
In the second argument of `map1', namely `[1 .. 10]'
In the expression: map1 (* 2) [1 .. 10]
*Main> map2 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map3 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map4 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
Si agrego un tipo de firma a map1, todo está bien.
map1 :: Eq a => (a -> b) -> [a] -> [b]
Las dos primeras funciones parecen más o menos lo mismo para mí, así que supongo que mi pregunta es, simplemente, "¿Qué está pasando aquí?"
No estoy seguro si tiene razones específicas para escribir de esta manera. ¿Por qué no usa [] como caso base para la recursión en lugar de (x: [])? Ninguna de sus funciones funcionará con la lista vacía. –