44

A quick question, is there an operator in Haskell that works like the dollar sign but gives precedence to the left hand side. I.E. instead of

f (x 1) 

being written as

f $ x 1

I'd like to write it as

x 1 $ f

This is purely a stylistic thing. I'm running a sequence of functions in order and it would be nice if I could write them left to right to match that I read left to right. If there an operator for this?

[update] A couple of people have asked if I can't define my own. In answer, I wanted to check there wasn't an existing operator before I reinvented the wheel.

5
  • 6
    This is like F#'s pipeline composition operator. Related discussion (on why it's not built into Haskell): stackoverflow.com/questions/1457140/… Commented Nov 3, 2010 at 18:20
  • It looks like the answer to my question is "no". Thank you :) Commented Nov 3, 2010 at 18:26
  • 2
    You realize you're combining both left-to-right and right-to-left application in the same expression, don't you? Most people I think would baulk at this. Reverse application is the so called T-combinator. It was often denoted with (#) a few years ago, but now # is a special symbol in GHC, so it is no longer used much. Commented Nov 3, 2010 at 18:30
  • you want: f (g 1). Why not just f . g $ 1? Commented Oct 31, 2011 at 15:13
  • @demi I believe OP is looking to express f (g 1) in a left-to-right pipeline. f . g $ 1 is the opposite of that Commented May 19, 2020 at 15:44

6 Answers 6

48

As of GHC 7.10 (base 4.8.0.0), & is in Data.Function: https://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Function.html

Sign up to request clarification or add additional context in comments.

Comments

36

In Haskell you can use flip to change arguments' order of any binary function or operator:

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

1 Comment

Does it keep the same operator precedence?
21

I do not know, whether there is an standart operator, but what prevents you from writing your own? This works in 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: searching on hoogle for a -> (a -> b) -> b (it is the type of this operator) found nothing useful.

5 Comments

Looks I'll be using this, thank you. An £ appeals to me for the operator.
@Benjamin Confino: Puns are always enjoyable, but for real-world use I'd suggest considering |>. As noted above, that operator in F# does exactly what you're looking for, so using the same name will help people understand your code more easily.
It is one of Haskell's real strengths that you can write your own control flow operators. Haskell doesn't have a "loop" construct? No problem! Just write your own.
|> is used by Data.Sequence. # sounds like a better idea.
Link: Hoogle search for a -> (a -> b) -> b. The only results with that exact type are ($) and ($!).
10

This combinator is defined (tongue in cheek) in the data-aviary package:

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

Although actually using that package is a rather silly thing to do, reading the source is fun, and reveals that this combinator is formed via the magic incantation of flip id (or, in ornithological parlance, cardinal idiot).

1 Comment

caridinalIdiot is a magnificent combinator name!
4

I am not aware of any standard version, but I've seen (#) used for that purpose in a couple places. The one in particular that comes to mind is HOC, which uses it in an idiom like:

someObject # someMessage param1 param2

I seem to recall seeing other "object-oriented" libraries using the # operator in the same way, but cannot remember how many or which ones.

1 Comment

Wash uses (#). Erik Meijer, Daan Leijen and James Hook used it to script MS Agent with Active Haskell (a Haskell-COM bridge). Possibly the initial Haskell / ObjectiveC bridge also used (#).
-1

Can't you just redefine $.

let ($) x f = f x

Or just choose a different operator, like $$

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.