Ich habe neulich gerade das Lernen von Youahaskell beendet und habe versucht, die Monomorphismus-Einschränkung zu verstehen, wie sie im Haskell-Wiki beschrieben wird . Ich denke, ich verstehe, wie der MR wiederholte Auswertungen verhindern kann, aber ich verstehe nicht, warum diese wiederholten Auswertungen mit weitaus einfacheren Mitteln nicht vermieden werden können.
Das konkrete Beispiel, an das ich denke, ist das, das im Wiki verwendet wird:
f xs = (len,len)
where
len = genericLength xs
Wo genericLength
ist der Typ Num a => [b] -> a
.
Offensichtlich muss genericLength xs
nur einmal berechnet werden, um auszuwerten (len,len)
, da es die gleiche Funktion mit den gleichen Argumenten ist. Und wir brauchen keine Aufrufe von f
zu sehen, um das zu wissen. Warum kann Haskell diese Optimierung nicht durchführen, ohne eine Regel wie die MR einzuführen?
Die Diskussion auf dieser Wiki-Seite sagt mir, dass es etwas mit der Tatsache zu tun hat, dass Num
es sich eher um eine Typenklasse als um einen konkreten Typ handelt. Sollte es jedoch beim Kompilieren nicht offensichtlich sein, dass eine reine Funktion denselben Wert zurückgibt. -und damit die gleiche konkrete Art von Num - wenn zweimal die gleichen Argumente gegeben werden?
f [] :: (Int, Float)
. Jetzt macht es vollkommen Sinn. Vielen Dank.It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.
Ich denke, die bessere Sichtweise ist, dass die Typeclass-Instanz tatsächlich ein zusätzliches Argument istgenericLength
und der Compiler nicht davon überzeugt ist, dass es in beiden Aufrufen die gleichen Argumente gibt.a = uncurry (==) $ f [1, 2, 3]
so zu optimieren, dass nur die Länge von[1, 2, 3]
einmal überprüft wird ? Wenn ja, dann bin ich wirklich verwirrt, was die Monomorphismus-Beschränkung tatsächlich für Sie bedeutet. Wenn nein, warum nicht?