Упорядочивание параметров для использования каррирования

93

Я дважды недавно реорганизовал код, чтобы изменить порядок параметров, потому что было слишком много кода, где хаки вроде flipили \x -> foo bar x 42происходили.

Какие принципы помогут мне лучше всего использовать каррирование при разработке сигнатуры функции?

Джон Ф. Миллер
источник

Ответы:

111

Для языков, которые легко поддерживают каррирование и частичное применение, есть одна убедительная серия аргументов, исходная от Криса Окасаки:

  • Поместите структуру данных в качестве последнего аргумента

Зачем? Затем вы можете красиво составлять операции с данными . Напр insert 1 $ insert 2 $ insert 3 $ s. Это также помогает функциям в состоянии .

Стандартные библиотеки, такие как «контейнеры», следуют этому соглашению .

Иногда приводятся альтернативные аргументы, чтобы поместить структуру данных на первое место, чтобы ее можно было закрыть, давая функции статической структуры (например, поиск), которые являются немного более краткими. Однако, по общему мнению, это не лучший вариант, особенно потому, что он подталкивает вас к коду, сильно заключенному в скобки.

  • Ставьте самые разные аргументы последними

Для рекурсивных функций обычно помещают аргумент, который больше всего изменяется (например, аккумулятор), в качестве последнего аргумента, а аргумент, который изменяется меньше всего (например, аргумент функции) в начале. Это хорошо сочетается с последним стилем структуры данных.


Краткое изложение взгляда Окасаки дано в его библиотеке Эдисона (опять же, другой библиотеке структур данных):

  • Частичное применение : аргументы, которые с большей вероятностью будут статичными, обычно появляются перед другими аргументами, чтобы облегчить частичное применение.
  • Коллекция отображается последней : во всех случаях, когда операция запрашивает отдельную коллекцию или изменяет существующую коллекцию, аргумент коллекции отображается последним. Это что-то вроде стандарта де-факто для библиотек структуры данных Haskell, который придает определенную согласованность API.
  • Самый обычный порядок : там, где операция представляет собой известную математическую функцию для более чем одной структуры данных, аргументы выбираются в соответствии с наиболее обычным порядком аргументов для функции.
Дон Стюарт
источник
Как следствие первого пункта маркера, также поместите аргумент, который может находиться в структуре данных, последним. Это делает карту, фолд и друзей чище. tl; dr вещь в списке идет последней.
Джон Ф. Миллер
1
В любом случае поиск нельзя связать цепочкой, поэтому первый пункт не поддерживает этого. haskell.org/haskellwiki/Parameter_order приводит убедительный аргумент наоборот: «Поскольку объекты типа Map представляют сопоставления, естественно иметь некоторую функцию, которая преобразует объект Map в представляемую функцию».
Brandon
11

Сначала разместите аргументы, которые вы, скорее всего, будете использовать повторно. Аргументы функции - отличный тому пример. Скорее всего, вы захотите использовать map fдва разных списка, чем сопоставить множество различных функций с одним и тем же списком.

хаммар
источник
5
Если вы на самом деле сопоставляете множество функций с одним и тем же списком, возможно, вам следует map ($myList)вместо этого составить список функций и поверх этого списка.
Squidly
3

Я обычно делаю то же, что и вы: выбираю какой-нибудь порядок, который кажется хорошим, а затем реорганизую его, если оказывается, что другой порядок лучше. Порядок во многом зависит от того, как вы собираетесь использовать функцию (естественно).

август
источник