2010-11-03 2 views
32

Быстрый вопрос: есть ли оператор в Haskell, который работает как знак доллара, но имеет преимущество перед левой стороной. И.Е. вместо

f (x 1) 

записывается в

f $ x 1 

Я хотел бы написать это как

x 1 $ f 

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

[обновление] Несколько человек спросили, не могу ли я определить свою собственную. В ответ я хотел проверить, не существовал ли оператор, прежде чем я заново изобрел колесо.

+4

Это подобен оператору компоновки трубопровода F #. Связанная дискуссия (о том, почему она не встроена в Haskell): http://stackoverflow.com/questions/1457140/haskell-composition-vs-fs-pipe-forward-operator –

+0

Похоже, что ответ на мой вопрос «нет», ,Спасибо :) –

+2

Вы понимаете, что вы комбинируете приложение слева направо и справа налево в том же выражении, не так ли? Большинство людей, которые, как я думаю, будут болеть. Обратное приложение - это так называемый T-combinator. Он часто обозначался (#) несколько лет назад, но теперь # является специальным символом в GHC, поэтому он больше не используется. –

ответ

19

Я не знаю, есть ли стандартный оператор, но что мешает вам писать свои собственные? Это работает в GHCI:

Prelude> let a $> b = b a 
Prelude> 1 $> (+2) 
3 
Prelude> sum [1, 2] $> (+2) 
5 
Prelude> map (+2) [1, 2] $> map (+3) 
[6,7] 

UPDATE: поиск по hoogle для a -> (a -> b) -> b (это тип этого оператора) не нашел ничего полезного.

+4

Выглядит, я буду использовать это, спасибо. Е обращение к мне за оператора. –

+5

@Benjamin Confino: Пунцы всегда приятны, но для реального использования я предлагаю рассмотреть '|>'. Как отмечалось выше, этот оператор в F # выполняет именно то, что вы ищете, поэтому использование того же имени поможет людям лучше понять ваш код. –

+2

Это одна из сильных сторон Хаскелла, которую вы можете написать своим собственным операторам управления потоком. У Haskell нет конструкции «loop»? Нет проблем! Просто напишите свое. –

-1

Не можете ли вы просто переопределить $.

let ($) x f = f x 

Или просто выбрать другой оператор, как $$

+3

Переопределение стандартного оператора - это не очень хорошая идея. – michau

4

Я не знаю ни стандартной версии, но я видел (#) используется для этой цели в паре мест. Один, в частности, что приходит на ум HOC, который использует его в идиомы, как:

someObject # someMessage param1 param2 

Кажется, я припоминаю видеть другие «объектно-ориентированный» библиотеки, используя оператор # таким же образом, но не могу вспомнить сколько или каких.

+2

Wash использует (#). Эрик Мейер, Даан Лейен и Джеймс Хук использовали его для написания MS Agent с Active Haskell (мост Haskell-COM). Возможно, также использовался начальный мост Haskell/ObjectiveC (#). –

10

Этот комбинатор определяется (языком в щеку) в data-aviary упаковке:

Prelude Data.Aviary.BirdsInter> 1 `thrush` (+2) 
Loading package data-aviary-0.2.3 ... linking ... done. 
3 

Хотя на самом деле с помощью этого пакета является довольно глупо, что нужно сделать, прочитав источник это весело, и показывает, что this combinator формируется через магическое заклинание flip id (или, на орнитологическом языке, cardinal idiot).

+4

'' caridinalIdiot'' - великолепное имя комбинатора! – sclv

24

В Haskell вы можете использовать flip для изменения порядка Аргументы любой бинарной функции или оператора:

ghci> let (|>) = flip ($) 
ghci> 3 |> (+4) |> (*6) 
42 
+0

Очень гладкое решение! –

Смежные вопросы