Я сподобился написать еще одну статью о ФП на русском. На этот раз - о бесконечных списках и ленивых вычислениях (в стиле "Tying The Knot", если кто в курсе). Буду рад, если вы прочтете и покритикуете.
1. Чистить от лишних слов. Для этого - читать Нору Галь, "Слово живое и мёртвое". У вас лишних слов немного, но есть. Упрощать язык. "Описание ... выглядит так:" -> "правила игры", или вообще ничего. 2. Это не разные описания, это разные формы одной игры. 3. Позиции, наверное, не оптимальные, а выигрышные. 4. Название строки "Номер позиции (n)" лишнее, оставить только "№". 5. К самым интересным (и самым сложным) хаскельным строкам я бы всё-таки приложил "русский подстрочник" вроде:
column = zipWith (+) [1..] row
column = это список сумм ряда натуральных чисел и ряда row
Что делает zipWith, я знаю, так что в доку лезть не стал. Замечание в том, что проще прочесть одно предложение в основном тексте, чем ходить по ссылке. Тем более что в ссылке довольно много информации. Да, немного не прав с комментарием, не "список", а "блок кода, вычисляющий список", или типа того.
Так-таки совсем ничего, или понятно хоть что-то, а с остальным - вопросы?
Я просто не совсем представляю себе, как можно иначе нарисовать producer-ов и consumer-ов потенциально бесконечных списков, тем более - взаиморекурсивных.
Как, например, нарисовать, что результатом "zipWith (+) row [1..]" будет thunk, который при вычислении выдаст список, голова которого - сумма первых эл-тов исходых списокв, а хвост - thunk, вычисляющий "zipWith (+)" от того, что осталось?
Я попытался представить схему по-своему и вот что у меня получилось: http://spreadsheets.google.com/pub?key=pHugjZLAJhuDLoQ2nScH9Vg Конечно не хватает понятий thunk и из-за этого наверное не понятна магия с отниманием winning_positions, ведь он тоже бесконечный, но при этом оно работает :)
Спасибо, исправил, не совсем так но все же - нюанс с первой итерацией - scanl не применяет функцию в первый раз, и это спасает ситуацию с "зацикливанием" рекурсии по-моему (я понял!? :)
Странно, что на zvon.org в определении сказано что scanl применяет второй аргумент к первому элементу списка и так далее, но это на самом деле так только со второй итерации, и даже у них в примере это видно, или я не понял? :)
(no subject)
Date: 2007-08-12 07:45 pm (UTC)"Описание ... выглядит так:" -> "правила игры", или вообще ничего.
2. Это не разные описания, это разные формы одной игры.
3. Позиции, наверное, не оптимальные, а выигрышные.
4. Название строки "Номер позиции (n)" лишнее, оставить только "№".
5. К самым интересным (и самым сложным) хаскельным строкам я бы всё-таки приложил "русский подстрочник" вроде:
(no subject)
Date: 2007-08-12 08:13 pm (UTC)5. А там zipWith - это ссылка на страницу документации с примерами. В том числе там есть пример с (+). Ссылка не помогла или ее не видно?
(no subject)
Date: 2007-08-13 07:46 am (UTC)Да, немного не прав с комментарием, не "список", а "блок кода, вычисляющий список", или типа того.
(no subject)
Date: 2007-08-13 08:21 am (UTC)(no subject)
Date: 2007-08-13 01:55 am (UTC)Тоже есть электронный вариант в Сети.
(no subject)
Date: 2007-08-12 07:47 pm (UTC)(no subject)
Date: 2007-08-12 08:05 pm (UTC)Я просто не совсем представляю себе, как можно иначе нарисовать producer-ов и consumer-ов потенциально бесконечных списков, тем более - взаиморекурсивных.
Как, например, нарисовать, что результатом "zipWith (+) row [1..]" будет thunk, который при вычислении выдаст список, голова которого - сумма первых эл-тов исходых списокв, а хвост - thunk, вычисляющий "zipWith (+)" от того, что осталось?
(no subject)
Date: 2007-08-13 01:57 am (UTC)(no subject)
Date: 2007-08-13 07:48 am (UTC)(no subject)
Date: 2007-08-22 06:19 pm (UTC)Конечно не хватает понятий thunk и из-за этого наверное не понятна магия с отниманием winning_positions, ведь он тоже бесконечный, но при этом оно работает :)
(no subject)
Date: 2007-08-22 09:19 pm (UTC)[1..] : (remove (1,2) [1..])
[1..]:[3..]:(remove (3,5) [3..])
[1..]:[3..]:[4,6..]:(remove (4,7) [4.6..])
[1..]:[3..]:[4,6..]:[6,8..]:(remove (6,10) [6,8..])
(no subject)
Date: 2007-08-22 10:41 pm (UTC)Странно, что на zvon.org в определении сказано что scanl применяет второй аргумент к первому элементу списка и так далее, но это на самом деле так только со второй итерации, и даже у них в примере это видно, или я не понял? :)
(no subject)
Date: 2007-08-23 06:24 am (UTC)scanl f q ls = q : case ls of
[] -> []
x:xs -> scanl f (f q x) xs
На zvon.org все правильно сказано про применение, но не сказано про порядок выдачи результатов :)
(no subject)
Date: 2007-08-13 12:11 pm (UTC)(no subject)
Date: 2007-08-13 07:14 pm (UTC)