Я читал Real World Haskell , и я близок к концу, но вопрос стиля тянул меня к операциям (.)
и ($)
.
Когда вы пишете функцию, которая является композицией других функций, вы пишете ее так:
f = g . h
Но когда вы применяете что-то к концу этих функций, я пишу это так:
k = a $ b $ c $ value
Но книга напишет это так:
k = a . b . c $ value
Теперь, для меня они выглядят функционально эквивалентными, они делают то же самое в моих глазах. Однако чем больше я смотрю, тем больше я вижу людей, пишущих свои функции так, как это делает книга: сначала скомпоновайте с (.)
, а затем только в конце, используйте ($)
, чтобы добавить значение для оценки партии (никто не делает это со многими долларовыми композициями).
Есть ли причина, по которой книги лучше использовать, чем все символы ($)
? Или есть лучшая практика, которую я не получаю? Или это излишне, и мне вообще не стоит об этом беспокоиться?
Думаю, я могу ответить на этот вопрос от авторитета.
Есть ли причина для использования книги способом, который намного лучше, чем использование всех символов ($)?
Нет особой причины. Мы с Брайаном предпочитаем уменьшать линейный шум. .
тише, чем $
. В результате в книге используется f. грамм . h $ x
синтаксис.
Это просто вопрос стиля. Однако то, как это написано в книге, имеет для меня больше смысла. Он объединяет все функции, а затем применяет их к значению.
Ваш метод выглядит странно, а последний $
не нужен.
Однако на самом деле это не имеет значения. В Haskell обычно есть много-много правильных способов сделать то же самое.
На ветке haskell-cafe есть интересное обсуждение этого вопроса. По-видимому, существует точка зрения меньшинства, согласно которой правильная ассоциативность $
"просто неверна" , и выбор f. грамм . h $ x
вместо f $ g $ h $ x
- это один из способов обойти проблему.
Они действительно эквивалентны: имейте в виду, что оператор $
, по сути, ничего не делает. f $ x
оценивается как f x
. Целью $
является его фиксированное поведение: правоассоциативный и минимальный приоритет. После удаления $
и использования круглых скобок для группировки вместо приоритета инфиксов фрагменты кода выглядят следующим образом:
k = a (b (c (value)))
и
k = (a . b . c) value
Причина предпочтения . Версия
по сравнению с версией $
является той же причиной, по которой они предпочитают обе версии, а не версии в скобках выше: эстетическая привлекательность.
Хотя некоторые могут задаться вопросом, основано ли использование инфиксных операторов вместо круглых скобок на подсознательном побуждении избежать любого возможного сходства с Лиспом (шутка ... я думаю?).
Для меня ответ: (а) аккуратность, как сказал Don; и (б) я обнаружил, что когда я редактирую код, моя функция может оказаться в стиле без точек, и тогда все, что мне нужно сделать, это удалить последний $
вместо того, чтобы возвращаться и менять все. Незначительный момент, конечно, но приятный.
Я бы добавил это в f. g $ x
, f. g
- значимая синтаксическая единица.
Между тем, в f $ g $ x
, f $ g
не имеет смысла. Цепочка $
, возможно, более обязательна - сначала получить результат g
of x
, затем do f
к нему, затем do foo
к нему, затем и т. д.
Между тем цепочка .
, возможно, более декларативен и в некотором смысле ближе к представлению, ориентированному на потоки данных - составляет ряд функций и в конечном итоге применяет их к чему-то.