Understanding Haskell recursion in functions -
i've been using few resources haskell: learn haskell , wikibook. however, i'm struggling find explanation helps me understand recursion bit more. i've attached sample piece of code 'learn haskell' book partially understand.
maximum' :: (ord a) => [a] -> maximum' [] = error "maximum of empty list" maximum' [x] = x maximum' (x:xs) | x > maxtail = x | otherwise = maxtail maxtail = maximum' xs i understand of above code until last line 'where maxtail = maximum' xs'. don't understand how code evaluated return maximum, calling maximum'. or how knows maximum' highest element of list.
another example:
reverse' :: [a] -> [a] reverse' [] = [] reverse' (x:xs) = reverse' xs ++ [x] understand until reverse' called on tail of list. in other words, how know reverse' means reverse tails elements.
i appreciate explanation, , apologies if it's simple, i'm new language.
going through lines, line line, understand better:
1| maximum' :: (ord a) => [a] -> 2| maximum' [] = error "maximum of empty list" 3| maximum' [x] = x 4| maximum' (x:xs) | x > maxtail = x | otherwise = maxtail maxtail = maximum' xs in line 1: list of a's , return 1 element of type. plus elements in list have ordable, can put them order.
in line 2: have edge case, if empty list input, there can't "highest value" in empty list, end function error.
in line 3: have edge case, if list 1 element, element has highest element, return it.
in line 4: use pattern matching match first element(x) , rest of list(xs). check if x bigger maxtail, maxtail result of function call maximum' rest of list xs.
if x bigger maxtail return x , otherwise maxtail bigger x , return maxtail.
i think example numbers should here:
input:
[2, 5, 4, 13] call:
maximum' [2, 5, 4, 13] what happens:
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 → ───────────┘ in second example it's pretty same:
1| reverse' :: [a] -> [a] 2| reverse' [] = [] 3| reverse' (x:xs) = reverse' xs ++ [x] in line 1: list of a's , return list of a's.
in line 2: have edge case, if empty list, reversed list empty.
in line 3: again use pattern matching match first element(x) of list , tail(xs) of it.
now use ++ append 2 lists together, first element of list reversed tail.
and again hope example bit clearer:
input:
[1, 2, 3] call:
reverse' [1, 2, 3] what happens:
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' [] = [] → ──────────────────┘
Comments
Post a Comment