Идиомы композиции (.) И приложения ($) функции Haskell: правильное использование - PullRequest
121 голосов
/ 13 июня 2010

Я читал Real World Haskell , и я близок к концу, но вопрос стиля меня теребил из-за операторов (.) и ($).

Когда вы пишете функцию, которая является композицией других функций, вы пишете ее так:

f = g . h

Но когда вы применяете что-то к концу этих функций, я пишу это так:

k = a $ b $ c $ value

Но книга напишет это так:

k = a . b . c $ value

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

Есть ли причина, по которой книги лучше использовать, чем все символы ($)?Или есть лучшая практика, которую я не получаю?Или это излишне, и мне вообще не стоит об этом беспокоиться?

Ответы [ 7 ]

143 голосов
/ 13 июня 2010

Полагаю, я могу ответить на этот вопрос от авторитета.

Есть ли причина, по которой использование книг намного лучше, чем использование всех ($) символов?

Там нет особой причины.Мы с Брайаном предпочитаем уменьшать шум в линии.. тише, чем $.В результате книга использует синтаксис f . g . h $ x.

52 голосов
/ 13 июня 2010

Они действительно эквивалентны: имейте в виду, что оператор $, по сути, ничего не делает.f $ x оценивается как f x.Целью $ является его поведение с фиксированностью: правоассоциативное и минимальное преимущество.После удаления $ и использования скобок для группировки вместо приоритета инфикса фрагменты кода выглядят следующим образом:

k = a (b (c (value)))

и

k = (a . b . c) value

Причина, по которой версия . предпочтительнееверсия $ - это та же причина, по которой они предпочитают обе версии, а не версию, заключенную в скобки: эстетическая привлекательность.

Хотя некоторые могут задаться вопросом, основано ли использование инфиксных операторов вместо скобок на подсознательном побуждении избегать любых возможныхСходство с Лиспом (шучу ... думаю?).

37 голосов
/ 22 июня 2010

Я бы добавил, что в f . g $ x, f . g является значимой синтаксической единицей.

Между тем, в f $ g $ x, f $ g не является значимой единицей. Цепочка $, возможно, является более императивной - сначала получите результат g из x, , затем do f, затем до foo, , затем и т. Д.

Между тем цепочка из ., возможно, является более декларативной и в некотором смысле ближе к представлению, ориентированному на поток данных - составляет ряд функций и в конечном итоге применяет их к чему-либо.

18 голосов
/ 13 июня 2010

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

13 голосов
/ 13 июня 2010

Есть интересное обсуждение этого вопроса на этой ветке haskell-cafe .Очевидно, существует точка зрения меньшинства, которая считает, что правильная ассоциативность $ равна "просто неправильно" , и выбор f . g . h $ x вместо f $ g $ h $ x является одним из способов обойти проблему.

3 голосов
/ 13 июня 2010

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

Ваш метод выглядит просто странно, а последний $ не нужен.

Однако это действительно не имеет значения.В Хаскеле обычно есть много правильных способов сделать то же самое.

0 голосов
/ 12 сентября 2015

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

Если вы объявляете новую бессмысленную функцию f . g . h, то значение, которое вы передадите, будет применено автоматически. Однако, если вы напишите f $ g $ h, это не будет работать.

Я думаю, что причина, по которой автор предпочитает метод композиции, заключается в том, что он приводит к хорошей практике построения функций.

...