Idąc za pośrednictwem linii, linia po linii, więc mam nadzieję, że rozumieją to lepiej:
1| maximum' :: (Ord a) => [a] -> a
2| maximum' [] = error "maximum of empty list"
3| maximum' [x] = x
4| maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
W wierszu 1: mówisz, że masz listę A i zwraca jeden element tego typu. Dodatkowo elementy na tej liście muszą być uporządkowane, abyś mógł je umieścić w zamówieniu.
W linii 2: masz przypadek skrajny, gdzie mówisz, że jeśli otrzymasz pustą listę jako dane wejściowe, nie może być "najwyższej wartości" na tej pustej liście, więc kończysz funkcję z błędem .
W linii 3: masz inny przypadek na krawędzi, gdzie mówisz, że jeśli otrzymasz listę z jednym elementem, element ten musi być najwyższym elementem, więc go zwrócisz.
W wierszu 4: dopasowujesz wzorce do pierwszego elementu (x
), a resztę listy (xs
). Następnie sprawdź, czy x
jest większy niż maxTail
, gdzie maxTail
wynik wywołania funkcji maximum'
z resztą listy xs
.
Jeśli x
jest większy niż maxTail
potem wrócisz x
i inaczej maxTail
jest większy niż x
i wrócisz maxTail
.
myślę przykład z niektórymi numerami powinny również pomóc tutaj:
wejściowe:
[2, 5, 4, 13]
wezwanie:
maximum' [2, 5, 4, 13]
Co się dzieje:
maximum' (x : xs)
↓ ↓
maximum' (2:[5, 4, 13])
│
↓ result 13
x > maxTail = x ↑
2 > maximum' [5, 4, 13] = x //2 > 13 = 13 ← ────┐
│ │
└ maximum' (x : xs) │
↓ ↓ │
maximum' (5:[4, 13]) │
│ │
↓ ↑
x > maxTail = x │
5 > maximum' [4, 13] = x //5 > 13 = 13 ← ─────┐
│ │
└ maximum' (x: xs) │
↓ ↓ │
maximum' (4:[13]) │
│ │
↓ ↑
x > maxTail = x │
4 > maximum' [13] = x //4 > 13 = 13 ┐
│ │
└ maximum' [x] = x ↑
maximum' [13] = 13 → ───────────┘
W drugim przykładzie jest to niemal tak samo:
1| reverse' :: [a] -> [a]
2| reverse' [] = []
3| reverse' (x:xs) = reverse' xs ++ [x]
W wierszu 1: mówisz, że masz listę A i zwróci listę ciągu roku.
W linii 2: masz przypadek skrajny, gdzie mówisz, że jeśli otrzymasz pustą listę, odwrócona lista jest również pusta.
W linii 3: ponownie użyjesz dopasowywania wzorów, aby dopasować pierwszy element (x
) listy i ogon() z tej listy.
Teraz wystarczy użyć ++
, aby dołączyć dwie listy razem, co jest pierwszym elementem listy z odwróconym ogonem.
I znowu mam nadzieję, że na przykładzie będzie to nieco wyraźniej:
wejściowe:
[1, 2, 3]
wezwanie:
reverse' [1, 2, 3]
Co się dzieje:
reverse' (x : xs)
↓ ↓
reverse' (1:[2, 3])
│ result [3, 2, 1]
↓ ↑
(reverse' [2, 3]) ++ [1] //[3, 2] ++ [1] = [3, 2, 1] ← ────┐
│ │
└ reverse' (x: xs) │
↓ ↓ │
reverse' (2:[3]) │
│ ↑
↓ │
(reverse' [3]) ++ [2] //[3] ++ [2] = [3, 2] ← ───┐ → ┘
│ │
└ reverse' (x:xs) │
↓ ↓ │
reverse' (3:[]) │
│ ↑
↓ │
(reverse' []) ++ [3] //[] ++ [3] = [3] ┐ → ┘
│ ↑
└ reverse' [] = [] → ──────────────────┘
'reverse'' nie oznacza "odwrócić elementy ogon". 'reverse 'xs' oznacza" odwróć elementy ogonowe ", ponieważ' xs' to elementy ogonowe, a 'reverse' oznacza odwrócenie. – immibis
Należy zauważyć, że w przypadku rekursywnym funkcje "maximum" i "reverse" są wywoływane na _tail_ (tzn. Wszystko oprócz pierwszego elementu) danej listy, np. "maksimum" [1,2,3] 'jest stosowane rekurencyjnie na liście' [2,3] '. Chodzi o to, że maksymalna liczba liczb całkowitych to większa wartość 1. pierwszego elementu listy i 2. maksymalna reszta listy. Gdy dopasowywanie wzorca do listy przez '(x: xs)', 'x' jest pierwszym elementem listy, a' xs' jest resztą ("ogon"). –
"Skąd wiadomo, że odwrócenie" oznacza odwrócenie elementów ogona. " nie ma; ale możesz to udowodnić poprzez indukcję. Zacznij od '[]' i '[a]' przypadków; następnie sprawdź "[a, b]", ...., a następnie załóż, że to dotyczy ogólnej sprawy "[a, b, ..., n]" i udowodnij, że wynika to z następnej sprawy, "[ a, b, ..., n, m] 'również ulega odwróceniu. –