Я читал Real World Haskell , и я приближался к концу, но вопрос стиля был мелочным у меня делать с (.)
и ($)
операторами.
Когда вы пишете функцию, которая является композицией других функций, вы пишете ее так:
f = g . h
Но когда вы применяете что-то в конце этих функций, я пишу это так:
k = a $ b $ c $ value
Но книга написала бы это так:
k = a . b . c $ value
Теперь для меня они выглядят функционально эквивалентными, они делают то же самое в моих глазах. Однако чем больше я смотрю, тем больше я вижу людей, которые пишут свои функции так, как это делает книга: (.)
сначала составляйте, а затем только в конце используйте, ($)
чтобы добавить значение для оценки партии (никто не делает этого с многодолларовыми композициями) ,
Есть ли причина использовать книжный способ, который намного лучше, чем использование всех ($)
символов? Или здесь есть какая-то передовая практика, которую я не понимаю? Или это лишнее, и я не должен об этом вообще беспокоиться?
источник
k = a $ b $ c value
a . b $ c value
который мне не нравится так сильно, как третий пример, но он сохраняет несколько символов.Ответы:
Думаю, я могу ответить на этот вопрос авторитетно.
Особой причины нет. Мы с Брайаном предпочитаем уменьшать линейный шум.
.
тише чем$
. В результате в книге используетсяf . g . h $ x
синтаксис.источник
f.g.h
скорее думать о нем как о новом умном творенииf(g(h()))
. Теперь они вызывают новую, хотя и анонимную, функцию, которую они создали, а не просто связывают большой словарь заранее подготовленных вызовов функций, как пользователь PHP.Они действительно эквивалентны: имейте в виду, что
$
оператор, по сути, ничего не делает.f $ x
оценивается вf x
. Целью$
является его фиксированное поведение: правоассоциативный и минимальный приоритет. После удаления$
и использования скобок для группировки вместо приоритета инфиксов фрагменты кода выглядят следующим образом:и
Причина, по которой
.
версия предпочтительнее$
версии, та же, что и для обеих версий, заключенных в скобки выше: эстетическая привлекательность.Хотя некоторые могут задаться вопросом, основано ли использование инфиксных операторов вместо круглых скобок на каком-то подсознательном побуждении избежать любого возможного сходства с Лиспом (шутка ... я думаю?).
источник
Я хотел бы добавить , что в
f . g $ x
,f . g
является значимой синтаксической единицей.Между тем, in
f $ g $ x
,f $ g
не имеет смысла.$
Возможно, более важна цепочка - первый получить результатg
изx
, а затем сделатьf
его, а затем сделатьfoo
его, то и т.д.Между тем, цепочка,
.
возможно, более декларативна и в некотором смысле ближе к представлению, ориентированному на потоки данных - составляет ряд функций и в конечном итоге применяет их к чему-то.источник
$
Оператор , кажется, ведут себя аналогично<|
оператору в F #. На самом деле, я считаю, что оба они определены одинаково - в F #,(<|) a b = a b
и Haskella $ b = a b
, которые по сути эквивалентны.(<|) b a = a b
на F #, так как он используется как[1; 2; 3; 4; 5] <| List.map ((+) 1)
, если память не изменяет.<|
Оператор передает значение функции, а не передает функцию в значение -|>
вместо этого ваш пример кода будет работать с оператором.Для меня, я думаю, ответ: (а) аккуратность, как сказал Дон ; и (б) я обнаружил, что когда я редактирую код, моя функция может закончиться безточечным стилем, и тогда все, что мне нужно сделать, это удалить последнюю,
$
вместо того, чтобы возвращаться и менять все. Мелочь, конечно, но тонкость.источник
Есть интересное обсуждение этого вопроса на ветке haskell-cafe . По- видимому , есть меньшинство точка зрения , которая считает , что право ассоциативности
$
является «просто неправильно» , и выборf . g . h $ x
более чемf $ g $ h $ x
один из способов боковых шагового вопроса.источник
$!
него также есть «совершенно неправильная» правильная ассоциативность - почему $! оператор правоассоциативный? ,Это просто вопрос стиля. Однако то, как это написано в книге, имеет для меня больше смысла. Он объединяет все функции, а затем применяет их к значению.
Ваш метод просто выглядит странно, а последний
$
не нужен.Однако на самом деле это не имеет значения. В Haskell обычно есть много, много правильных способов сделать то же самое.
источник
Я понимаю, что это очень старый вопрос, но я думаю, что есть еще одна причина, о которой не упоминалось.
Если вы объявляете новую функцию без точек
f . g . h
, значение, которое вы передаете, будет автоматически применено. Однако если вы напишетеf $ g $ h
, это не сработает.Я думаю, что причина, по которой автор предпочитает метод композиции, заключается в том, что он приводит к хорошей практике построения функций.
источник