В чем разница между . (точка) и $ (знак доллара)?

В чем разница между точкой (.) и знаком доллара ($)?

Насколько я понимаю, они оба являются синтаксическим сахаром для того, чтобы не использовать скобки.

668
задан Matthias Braun 27 July 2019 в 13:04
поделиться

4 ответа

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

Например, допустим, у вас есть строка, которая гласит:

putStrLn (show (1 + 1))

Если вы хотите избавиться от этих скобок, любая из следующих строк также будет сделайте то же самое:

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

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

Возвращаясь к тому же примеру:

putStrLn (show (1 + 1))
  1. (1 + 1) не имеет входных данных и, следовательно, не может использоваться с . оператор.
  2. show может принимать Int и возвращать String .
  3. putStrLn может принимать String и возвращать ] IO () .

Вы можете связать show с putStrLn следующим образом:

(putStrLn . show) (1 + 1)

Если это слишком много круглых скобок, избавьтесь от них с помощью $ оператор:

putStrLn . show $ 1 + 1
1187
ответ дан 22 November 2019 в 21:40
поделиться

У них разные типы и разные определения:

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x

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

В некоторых случаях они взаимозаменяемы, но в целом это неверно. Типичный пример, где они находятся:

f $ g $ h $ x

==>

f . g . h $ x

Другими словами в цепочке из $ s, все, кроме последнего, можно заменить на .

179
ответ дан 22 November 2019 в 21:40
поделиться

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

id :: a -> a
id x = x

В то время как ($) выглядит так:

($) :: (a -> b) -> (a -> b)
($) = id

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

Использование ( $) обычно можно исключить, добавив скобки (если оператор не используется в разделе). Например: f $ gx становится f (gx) .

Использование (.) часто немного сложнее заменить; им обычно требуется лямбда или введение явного параметра функции. Например:

f = g . h

становится

f x = (g . h) x

становится

f x = g (h x)

Надеюсь, это поможет!

122
ответ дан 22 November 2019 в 21:40
поделиться

Краткая и приятная версия:

  • ($) вызывает функцию, которая является его левым аргументом, для значения, которое является его правым аргументом.
  • ( .) составляет функцию, которая является ее левым аргументом в функции, которая является ее правым аргументом.
58
ответ дан 22 November 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: