Acabei de terminar learnyouahaskell no outro dia e estava tentando entender a restrição de monomorfismo, conforme descrito no Wiki de Haskell . Acho que entendo como o MR pode impedir avaliações repetidas, mas não estou conseguindo entender por que essas avaliações repetidas não podem ser evitadas por meios muito mais diretos.
O exemplo específico que tenho em mente é o usado pelo wiki:
f xs = (len,len)
where
len = genericLength xs
Onde genericLength
é do tipo Num a => [b] -> a
.
Obviamente, genericLength xs
só precisa ser computado uma vez para avaliar (len,len)
, pois é a mesma função com os mesmos argumentos. E não precisamos ver nenhuma invocação f
para saber disso.Então, por que Haskell não pode fazer essa otimização sem introduzir uma regra como a MR?
A discussão nessa página da wiki me diz que tem algo a ver com o fato de Num
ser uma classe de tipo e não de concreto, mas mesmo assim, não deveria ser óbvio no tempo de compilação que uma função pura retornaria o mesmo valor - - e, portanto, o mesmo tipo concreto de Num - quando dados os mesmos argumentos duas vezes?
fonte
f [] :: (Int, Float)
. Agora faz todo o sentido. Obrigado.It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.
Eu acho que a melhor maneira de ver é que a instância da classe de tipo é efetivamente um argumento extragenericLength
e o compilador não está convencido de que é o mesmo argumento nas duas chamadas.a = uncurry (==) $ f [1, 2, 3]
Seria capaz de otimizar o site de chamada para verificar apenas a duração de[1, 2, 3]
uma vez? Se sim, então estou realmente confuso sobre o que a restrição de monomorfismo está realmente comprando para você, se não, por que não?