Да, возможно, вы сделали бы это в своем сценарии msbuild. Хотя я не могу дать вам точный ответ, посмотрите здесь на этот вопрос в SO Скопируйте все файлы и папки с помощью msbuild
Оператор $
предназначен для исключения скобок. Все, что появляется после него, будет иметь приоритет над всем, что предшествует.
Например, допустим, у вас есть строка, которая гласит:
putStrLn (show (1 + 1))
Если вы хотите избавиться от этих скобок, любая из следующих строк также будет сделайте то же самое:
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1
Основная цель .
Оператор заключается не в том, чтобы избегать скобок, а в цепочке функций. Он позволяет связать вывод того, что появляется справа, со вводом того, что появляется слева. Обычно это также приводит к меньшему количеству скобок, но работает по-другому.
Возвращаясь к тому же примеру:
putStrLn (show (1 + 1))
(1 + 1)
не имеет входных данных и, следовательно, не может использоваться с .
оператор. show
может принимать Int
и возвращать String
. putStrLn
может принимать String
и возвращать ] IO ()
. Вы можете связать show
с putStrLn
следующим образом:
(putStrLn . show) (1 + 1)
Если это слишком много круглых скобок, избавьтесь от них с помощью $
оператор:
putStrLn . show $ 1 + 1
У них разные типы и разные определения:
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, все, кроме последнего, можно заменить на .
Также обратите внимание, что ($)
- это функция идентификации, специализированная для типов функций . Функция идентификации выглядит так:
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)
Надеюсь, это поможет!
Краткая и приятная версия:
($)
вызывает функцию, которая является его левым аргументом, для значения, которое является его правым аргументом. ( .)
составляет функцию, которая является ее левым аргументом в функции, которая является ее правым аргументом. ($)
позволяет сцеплять функции без добавления скобок для контроля порядка вычисления:
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"
Одно приложение, которое полезно и потребовало меня некоторое время, чтобы выяснить из самого краткого описания , на котором вы узнаете Haskell : с:
f $ x = f x
и скобки Правая сторона выражения, содержащей инфикс-оператор, преобразует его в префиксную функцию, можно написать ($ 3) (4 +)
, аналогичный (++ ", мир") "привет «
.
Почему кто-нибудь сделает это? Для списков функций, например. Оба:
map (++", world") ["hello","goodbye"]`
и:
map ($ 3) [(4+),(3*)]
короче карта (\ x -> x ++ ", мир") ...
или карта (\ f -> f 3). ..
. Очевидно, что последние варианты будут более читаемыми для большинства людей.