Сейчас я застрял на вопросе из главы 7 IFPH.
Это Упражнение 7.1.2, которое гласит:
«Одно из определений sort
состоит в том, чтобы взять sort = foldr insert []
, где
insert x [] = [x]
insert x (y:ys) = if x <= y then x : y : ys else y : insert x ys
Дайте, в деталях, последовательности быстрого и ленивого сокращения вычислений для выражения sort [ 3,4,2,1]
, объясняя, где они различаются"
Теперь я начал с последовательного сокращения нетерпеливых вычислений, которое, как я полагаю, является самым внутреннимсокращением.
Мне это дает...
sort [3,4,2,1]
=> foldr insert [] [3,4,2,1]
=> insert 3 (foldr insert [] [4,2,1])
=> insert 3 (insert 4 (foldr insert [] [2,1]
=> insert 3 (insert 4 (insert 2 (foldr insert [] [1])))
=> insert 3 (insert 4 (insert 2 (insert 1 (foldr [] []))))
=> insert 3 (insert 4 (insert 2 (insert 1 [])))
=> insert 3 (insert 4 (insert 2 [1]))
=> insert 3 (insert 4 (1 : insert 2 []))
=> insert 3 (insert 4 (1 : [2]))
=> insert 3 (1 : insert 4 [2])
=> insert 3 (1 : 2 : insert 4 [])
=> insert 3 (1 : 2 : [4])
=> insert 3 [1,2,4]
=> 1 : insert 3 [2,4]
=> 1 : 2 : insert 2 : [4]
=> 1 : 2 : 3 : [4]
=> [1,2,3,4]
Отсортированный список.
Теперь для ленивых вычислений единственная последовательность сокращения, которую я могу придумать, точно такая же, как и для жадных вычислений. Конечно, Haskell выполняет крайнее левое внешнее вычисление для ленивых вычислений: но я не думаю, что он может работать с большей частью списка, пока внутренние вычисления не будут завершены.
Правильно ли это рассуждение? Интуиция говорит мне, что нет.
Было бы здорово, если бы кто-нибудь указал, как выполнить последовательность сокращения ленивых вычислений.
Спасибо