oft hilft es, einige Invarianten zu erfinden und einige Erhaltungsgesetze dafür aufzuschreiben. Hier bemerken, dass
reverse xs = reverse xs ++ []
reverse (x:xs) = (reverse xs ++ [x]) ++ []
= reverse xs ++ ([x] ++ [])
= reverse xs ++ (x:[])
reverse (x:(y:xs)) =
= reverse (y:xs) ++ (x:[])
= reverse xs ++ (y:x:[])
......
reverse (x:(y:...:(z:[])...)) =
= reverse [] ++ (z:...:y:x:[])
so, wenn wir
reverse xs = rev xs [] where
rev (x:xs) acc = rev xs (x:acc)
rev [] acc = acc
definieren wir gesetzt sind. :) Das heißt, für einen Anruf rev a b
, die Verkettung von umgekehrt a
und b
unter einer Transformation erhalten ein Kopfelement aus a
des Nehmens und vorangestellt, es zu b
, bisa
leer ist und dann b
es ist einfach. Dies kann auch bei der Verwendung von higher-order function until
nach der englischen Beschreibung ausgedrückt werden, als
{-# LANGUAGE TupleSections #-}
reverse = snd . until (null.fst) (\(a,b)-> (tail a,head a:b)) . (, [])
Wir definieren nun auch z eine revappend
Funktion, mit genau die gleichen internen Funktion mit einem kleinen Kniffe, wie wir es nennen:
revappend xs ys = rev xs ys where
rev (x:xs) acc = rev xs (x:acc)
rev [] acc = acc
tut '[Länge xs - 1, Länge xs - 2..0]' Arbeit? –
Wenn Sie sich mit der Rekursion noch nicht auskennen, sollten Sie, bevor Sie sich andere Implementierungen ansehen, versuchen, 'reverse' anders zu definieren, indem Sie Folgendes eingeben:' reverse [] = ...; reverse (x: xs) = ... 'und denke an es als" die Umkehrung der leeren Liste ist ... und die Umkehrung von 'x' in Übereinstimmung mit der Liste' xs' ist ... " – jberryman
Beachten Sie, dass es ist im Allgemeinen fraglich, um Listen nach Index zugreifen zu können. Sie sind speziell so konzipiert, dass Sie sie leicht rekursiv vom Kopf Element für Element dekonstruieren können, aber sehr schlecht funktionieren, wenn Sie ein Element an einer beliebigen Position anfordern. – leftaroundabout