Состав функции Хаскелла (.) и функции приложения ( $ ) идиомы: правильное использование


Я читал Реальный Мир Хаскелл, и я приближаюсь к концу, но вопрос стиля был придираться ко мне, чтобы сделать с (.) и ($) операторы.

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

f = g . h

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

k = a $ b $ c $ value

но книга будет писать это как это:

k = a . b . c $ value

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

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

7 120

7 ответов:

Я думаю, что могу ответить на это от власти.

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

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

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

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

и

k = (a . b . c) value

причина предпочтения . перед $ версия по той же причине для предпочтения обоих над очень заключенной в скобки версией выше: эстетическая привлекательность.

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

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

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

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

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

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

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

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

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

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

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

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