Ich gehe gerade durch das Lernen Sie ein Haskell Buch und ich bin neugierig, wie dieses besondere Beispiel funktioniert. Das Buch zeigt zunächst eine Implementierung von findKey
traditionelle Rekursion:Verwenden Sie falten weniger effizient als Standard-Rekursion
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey key [] = Nothing
findKey key ((k,v):xs) = if key == k
then Just v
else findKey key xs
Das Buch dann mit einer kürzeren Implementierung folgt bis mit foldr
findKey :: (Eq k) => k -> [(k,v)] -> Maybe v
findKey key = foldr (\(k,v) acc -> if key == k then Just v else acc) Nothing
Mit der Standard-Rekursion, sollte die Funktion sofort zurück, sobald es trifft das erste Element mit dem angegebenen Schlüssel. Wenn ich die foldr
Implementierung richtig verstehe, wird sie jedes Mal über die gesamte Liste iterieren, auch wenn sie mit dem ersten Element übereinstimmt, auf das sie gestoßen ist. Das scheint kein sehr effizienter Weg zu sein, mit dem Problem umzugehen.
Gibt es etwas, über das ich nicht weiß, wie die foldr
Implementierung funktioniert? Oder gibt es irgendeine Art von Magie in Haskell, die diese Implementierung nicht ganz so ineffizient macht, wie ich denke?
Hinweis: Der Compiler kann keine Eigenschaft Ihrer generischen rekursiven Definition verwenden. Der Compiler weiß jedoch, wie man 'foldr' über das Umschreiben von Regeln behandelt, was bedeutet, dass das Definieren von Funktionen über 'fold' dem Compiler ermöglicht, den Code mehr zu optimieren. – Bakuriu