Определение функций pointfree-style в функциональном программировании. Какие минусы / плюсы? - PullRequest
5 голосов
/ 10 сентября 2011

Каждый раз, когда я пишу что-то вроде

let scorePopulation f population =
  Array.map (fun i -> f i) population

, я спрашиваю себя, не лучше ли мне написать

let scorePopulation f =
  Array.map (fun i -> f i)

.Есть ли какое-либо преимущество в том, чтобы записать его в первой форме, а не во второй?

Кроме того, как бы вы назвали определение функции в первой форме и во второй форме?

Ответы [ 6 ]

12 голосов
/ 10 сентября 2011

Вы можете пойти еще дальше:

let scorePopulation = Array.map

Что касается преимуществ / недостатков, я думаю, что основной проблемой, как правило, будет удобочитаемость. Иногда легче понять, что делает функция, когда присутствуют все аргументы. В других случаях выигрывает тот факт, что вам не нужно составлять посторонние имена переменных.

10 голосов
/ 10 сентября 2011

На самом деле плюсы и минусы одинаковы: наименование.

Причиной этого является старая поговорка Фила Карлтона:

В компьютерной науке есть только две сложные проблемы. Аннулирование кэша и присвоение имен вещам.

Если называть вещи сложно (то есть дорого), то имена не должны тратиться на ненужные вещи. И наоборот, если у чего-то есть имя, это важно.

Стиль без точек позволяет вам пропустить имена.

Преимущество заключается в том, что он позволяет опустить нерелевантных имен.

Дело в том, что он позволяет опускать соответствующие имена.

7 голосов
/ 10 сентября 2011

Я бы сказал, что частичное применение является преимуществом функционального программирования.Почему бы не воспользоваться этим?Это приводит к уменьшению избыточности.

Еще одна вещь, о которой следует помнить, это ограничение значения [MSDN] Частично примененная функция без параметров является функцией значение .Истинные функции могут быть обобщены, но значения не могут.

6 голосов
/ 10 сентября 2011

Вы должны быть в состоянии назвать это так же, как в первом и втором примере. Этот метод обычно называется стиль без очков.

Это может быть лучше. Это короче, так что это плюс по умолчанию. Я согласен с этим предупреждением по ссылке выше:

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

Вы также теряете возможность дать параметру осмысленное имя, которое иногда может помочь пониманию.

5 голосов
/ 10 сентября 2011

Лично я ненавижу стиль без очков, я всегда нахожу его нечитаемым. Как уже упоминалось,

Вы также теряете возможность дать параметру осмысленное имя, что иногда может помочь пониманию.

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

Как кто-то еще упомянул, «ограничение значения» вступает в силу, если вы избавляетесь от всех параметров из универсальной функции, что является техническим ограничением, которое также не поощряет стиль без точек в F #.

2 голосов
/ 10 сентября 2011

Я часто предоставляю параметр, даже если могу опустить его для ясности. Когда я опускаю параметр, обычно это происходит потому, что тело функции сразу дает понять: i) что есть пропущенный параметр и ii) какова природа параметра. Например, я нахожу достаточным написать

let f = function [] -> "empty" | x::_ -> "not empty"

вместо

let f l = match l with [] -> "empty" | x::_ -> "not empty"

Более интересный пример - написать

let f = List.map g |> List.fold_left h

вместо

let f l = List.map g (List.fold_left h l)

Я нахожу первый более понятным. Преимущество здесь связано с доступностью интуитивно понятных операторов более высокого порядка, таких как |>, которые предусмотрены в Батареях.

...