Otros han abordado muchos aspectos de esta pregunta bastante bien. Me gustaría decir unas palabras sobre la razón detrás de por qué +
tiene el tipo de firma Num a => a -> a -> a
.
En primer lugar, la clase de tipo Num
no tiene forma de convertir una instancia artbitraria de Num
en otra. Supongamos que tengo un tipo de datos para números imaginarios; todavía son números, pero realmente no puedes convertirlos en un Int
.
En segundo lugar, ¿qué tipo de firma prefieres?
(+) :: (Num a, Num b) => a -> b -> a
(+) :: (Num a, Num b) => a -> b -> b
(+) :: (Num a, Num b, Num c) => a -> b -> c
Después de considerar las otras opciones, se dan cuenta de que a -> a -> a
es la opción más sencilla. Los resultados polimórficos (como en la tercera sugerencia anterior) son geniales, pero a veces pueden ser demasiado genéricos para ser usados convenientemente.
En tercer lugar, Haskell no es Blub. La mayoría, aunque podría decirse que no todas, las decisiones de diseño sobre Haskell no toman en cuenta las convenciones y expectativas de los lenguajes populares. Con frecuencia me gusta decir que el primer paso para aprender Haskell es desaprender primero todo lo que crees que sabes sobre programación. Estoy seguro de que la mayoría, si no todos, los Haskeller experimentados se han visto frustrados por la clase de Num y otras curiosidades de Haskell, porque la mayoría aprendió un lenguaje más "dominante" primero. Pero sé paciente, eventualmente alcanzarás Haskell nirvana. :)
Como dice el meme, "necesita más' fromIntegral' ". –
Me recuerda a 'x.f()' frente a 'g = x.f; g(); 'en Javascript. Apesta cuando las variables rompen la abstracción del modelo de sustitución. – hugomg