Acabo de terminar de aprender el otro día, y estaba tratando de dar sentido a la restricción de monomorfismo, como lo describe el Wiki de Haskell . Creo que entiendo cómo la MR puede evitar evaluaciones repetidas, pero no entiendo por qué esas evaluaciones repetidas no se pueden evitar por medios mucho más directos.
El ejemplo específico que tengo en mente es el que usa el wiki:
f xs = (len,len)
where
len = genericLength xs
donde genericLength
es de tipo Num a => [b] -> a
.
Obviamente, genericLength xs
solo necesita calcularse una vez para evaluar (len,len)
, ya que es la misma función con los mismos argumentos. Y no necesitamos ver ninguna invocación f
para saber eso. Entonces, ¿por qué Haskell no puede hacer esta optimización sin introducir una regla como el MR?
La discusión en esa página wiki me dice que tiene algo que ver con el hecho de que Num
es una clase de tipos en lugar de un tipo concreto, pero aun así, ¿no debería ser obvio en tiempo de compilación que una función pura devolvería el mismo valor? -y, por lo tanto, el mismo tipo concreto de Num, cuando se les dan los mismos argumentos dos veces
f [] :: (Int, Float)
. Ahora tiene mucho sentido. Gracias.It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.
Creo que la mejor forma de verlo es que la instancia de la clase de tipos es efectivamente un argumento adicionalgenericLength
y el compilador no está convencido de que sean los mismos argumentos en ambas llamadas.a = uncurry (==) $ f [1, 2, 3]
¿Podría optimizar ese sitio de llamadas para verificar solo la duración de[1, 2, 3]
una vez? Si es así, estoy realmente confundido sobre lo que la restricción de monomorfismo realmente te está comprando, si no, ¿por qué no?