Is there an inverse of the Haskell $ operator?
Asked Answered
Q

6

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.

Quartziferous answered 3/11, 2010 at 18:8 Comment(5)
This is like F#'s pipeline composition operator. Related discussion (on why it's not built into Haskell): #1457640Tolerate
It looks like the answer to my question is "no". Thank you :)Quartziferous
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.Waldenses
you want: f (g 1). Why not just f . g $ 1?Siberson
@Siberson I believe OP is looking to express f (g 1) in a left-to-right pipeline. f . g $ 1 is the opposite of thatFleabite
K
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

Krieger answered 11/7, 2015 at 1:49 Comment(0)
R
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
Robinson answered 4/11, 2010 at 11:20 Comment(1)
Does it keep the same operator precedence?Ti
E
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.

Eden answered 3/11, 2010 at 18:16 Comment(5)
Looks I'll be using this, thank you. An £ appeals to me for the operator.Quartziferous
@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.Bursiform
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.Venavenable
|> is used by Data.Sequence. # sounds like a better idea.Morry
Link: Hoogle search for a -> (a -> b) -> b. The only results with that exact type are ($) and ($!).Incurvate
T
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).

Theologue answered 4/11, 2010 at 2:43 Comment(1)
caridinalIdiot is a magnificent combinator name!Delvecchio
C
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.

Cristincristina answered 3/11, 2010 at 18:22 Comment(1)
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 (#).Waldenses
I
-1

Can't you just redefine $.

let ($) x f = f x

Or just choose a different operator, like $$

Ivanivana answered 3/11, 2010 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.