Кстати говоря о преобразованиях. Если бы ты с самого начала увидел, что функция двухместная, и прямо-таки напрашивается записать её инфиксно n `f` ((n-1) `f` (...(1 `f` x)...)), то сразу получил бы x `f'` 1 `f'` 2 `f'` ... `f'` n, где f' = flip f.
А насчёт антипаттерна... Конечно: chain_bad возвращает мега-функцию от одного аргумента x. Ну эту мегафункцию надо же где-то хранить, не так ли? В отличие от chain_good, которая благодаря каррингу не рожает мега-функцию, а терпеливо дожидается x и уже с ним проводит все вычисления.
Причём неважно, используешь в chain_bad энергичный foldl' или ленивые foldl, foldr. Просто в одном случае израсходуешь память, а во втором-третьем - выжрешь стек.
no subject
Если бы ты с самого начала увидел, что функция двухместная, и прямо-таки напрашивается записать её инфиксно
n `f` ((n-1) `f` (...(1 `f` x)...))
, то сразу получил быx `f'` 1 `f'` 2 `f'` ... `f'` n
, гдеf' = flip f
.А насчёт антипаттерна... Конечно: chain_bad возвращает мега-функцию от одного аргумента x. Ну эту мегафункцию надо же где-то хранить, не так ли?
В отличие от chain_good, которая благодаря каррингу не рожает мега-функцию, а терпеливо дожидается x и уже с ним проводит все вычисления.
Причём неважно, используешь в chain_bad энергичный foldl' или ленивые foldl, foldr. Просто в одном случае израсходуешь память, а во втором-третьем - выжрешь стек.
Отсюда мораль: карринг не самоцель :)