Порядок оценки функции makeSum в haskell
Я новичок в Haskell, и я рассматриваю порядок оценки как часть моих лекций в университете. У меня есть пример, который я не могу понять. Я знаю, что Haskell использует ленивое вычисление и что оно оценивает крайнее, самое левое. В этом случае я думаю, что это сама функция, которую я не понимаю.
c) Показать все шаги в оценке makeSum [3, 2, 7], используя следующее определение makeSum и foldr1.
makeSum [] = 0
makeSum xs = foldr1 add xs
where
add x y = x + y
foldr1 f [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)
Я получаю, что foldr1 берет функцию и список, и если список содержит один элемент, он возвращает элемент, и если список длиннее, он применяет функцию к первому и остальным элементам.
makeSum берет пустой список и возвращает ноль, и вот где я запутался. Если есть случай, когда он принимает пустой список, рекурсивный вызов не должен выглядеть так:
makeSum (x:xs) = foldr1 add xs
а не это:
makeSum xs = foldr1 add xs
Из чего я получаю makeSum берет список и добавляет элементы в него вместе?
Как мне это оценить?
2 ответа
makeSum [] = 0
makeSum xs = foldr1 add xs
where
add x y = x + y
эквивалентно альтернативе ОП
makeSum [] = 0
makeSum (x:xs) = foldr1 add (x:xs)
where
add x y = x + y
Дело в том, что в первом фрагменте, переменная xs
будет связан весь список. Также, xs
не пусто, потому что первая строка обрабатывает []
дело.
Нет необходимости совпадать с другим конструктором _:_
явно, универсальный шаблон как xs
делает ту же работу, в этом случае.
Как мне это оценить?
Итак, вам просто нужно тщательно расширить свой код, учитывая определения:
makeSum [3, 2, 7] --initial definition
foldr1 add [3, 2, 7] --substitute with makeSum xs = foldr1 add xs, being xs = [3,2,7]
add 3 (foldr1 add [2, 7]) --foldr1 f (x:xs) = f x (foldr1 f xs) being f = add and xs = [2,3,7]
add 3 (add 2 (foldr1 add [7])) --keep the recursive work
add 3 (add 2 (7))
3 + ((2 + 7)
3 + 9
12 --final result