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

Да, возможно, вы сделали бы это в своем сценарии msbuild. Хотя я не могу дать вам точный ответ, посмотрите здесь на этот вопрос в SO Скопируйте все файлы и папки с помощью msbuild

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

6 ответов

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

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

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
поделиться

($) позволяет сцеплять функции без добавления скобок для контроля порядка вычисления:

Prelude> head (tail "asdf")
's'

Prelude> head $ tail "asdf"
's'

Оператор compose (.) создает новую функцию без указания аргументов:

Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'

Prelude> let second = head . tail
Prelude> second "asdf"
's'

Приведенный выше пример спорно показателен, но на самом деле не демонстрирует удобства использования композиции. Вот еще одна аналогия:

Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"

Если мы используем третий только один раз, мы можем избежать его именования, используя лямбда:

Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"

Наконец, композиция позволяет нам избежать лямбда:

Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"
77
ответ дан 22 November 2019 в 21:40
поделиться
-

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

f $ x = f x

и скобки Правая сторона выражения, содержащей инфикс-оператор, преобразует его в префиксную функцию, можно написать ($ 3) (4 +) , аналогичный (++ ", мир") "привет «.

Почему кто-нибудь сделает это? Для списков функций, например. Оба:

map (++", world") ["hello","goodbye"]`

и:

map ($ 3) [(4+),(3*)]

короче карта (\ x -> x ++ ", мир") ... или карта (\ f -> f 3). .. . Очевидно, что последние варианты будут более читаемыми для большинства людей.

29
ответ дан 22 November 2019 в 21:40
поделиться
Другие вопросы по тегам:

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