В Haskell я часто пишу выражения с $. Я считаю это вполне естественным и читаемым, но иногда я читаю, что это плохая форма и не понимаю, почему это должно быть.
Является ли долларовый оператор ($) плохой формой? Зачем?
Ответ 1
Ниже приведены все хорошие формы:
foo = bar . baz . quux
foo x = bar . baz . quux $ x
foo x = (bar . baz . quux) x
foo x = bar (baz (quux x))
Я поместил их в грубый порядок моих предпочтений, хотя, как всегда, вкус меняется, и контекст может потребовать другого выбора. Я также иногда видел
foo = bar
. baz
. quux
когда каждый из подвыражений bar
, baz
и quux
длинный. Ниже приведена неправильная форма:
foo x = bar $ baz $ quux $ x
Есть две причины, почему это менее предпочтительно. Во-первых, меньшее количество подвыражений может быть скопировано и вставлено во вспомогательное определение во время рефакторинга; со всеми операторами ($)
, только подвыражения, которые включают аргумент x
, являются действительными рефакторингами, тогда как с операторами (.)
и ($)
даже вложенные подвыражения, такие как bar . baz
или baz . quux
, могут быть выведены в отдельное определение.
Вторая причина предпочтительности (.)
заключается в ожидании возможного изменения фиксированности ($)
; в настоящее время ($)
есть infixr
, что означает, что он присваивается вправо, например:
foo x = bar $ (baz $ (quux $ x))
Однако ($)
был бы полезен в большем количестве выражений, если бы он был infixl
; например, что-то вроде
foo h = f (g x) (h y)
foo h = f $ g x $ h y
foo h = (f $ g x) $ h y
... который в настоящее время не может быть выражен без круглых скобок. Пример "плохой формы" при анализе с приложением infixl
был бы
foo x = ((bar $ baz) $ quux) $ x
что означает нечто существенно иное. Итак, будущий код, избегая этой формы.