17

Writing Haskell programs I found myself in need of an operator like this.

(|>) :: a -> (a -> b) -> b
(|>) = flip ($)
infixl 0 |>

I think it is useful when glueing many functions together.

tText cs = someFun cs   |>
           lines        |>
           map (drop 4) |>
           reverse

I prefer it over . because with |> the order in which the functions are applied is the same as the order in which the functions are written.

tText' cs = reverse      . 
            map (drop 4) . 
            lines        . 
            someFun $ cs

Question is: is this (|>) something that already exists in the Prelude / some other basic library? Reimplementing simple stuff is something silly which I would like to avoid.

A Hoogle search did not help. Closest thing I found was >>> (Arrows), but it seems an overkill.

5
  • 3
    No, it doesn't, although as you say >>> does. There was another SO question about why F# uses |> where Haskell uses . and $, which is pretty relevant. (Note also, just for fun, that with . or >>>, you can write your function point-free: tText = reverse . map (drop 4) . lines . someFun, or tText = someFun >>> lines >>> map (drop 4) >>> reverse.) Mar 24, 2013 at 21:49
  • 1
    Some time ago, there was a conversation on the mailing list about adding this to the standard libraries. haskell.org/pipermail/libraries/2012-November/018832.html
    – Dan Burton
    Mar 24, 2013 at 22:44
  • 4
    "the order in which the functions are applied is the same as the order in which the functions are written." Well – that's the kind of thinking Haskellers avoid: you don't specify "do this, then with the result do that, then..." but focus on the desired result, so it's perfectly natural to start with the last calculation step. Also, what with lazy evaluation, this "last" step will actually be the first to be evaluated! — For the procedural kind of functions, the ones where you actually need to think in sequential steps, Haskell has Monads, whose do notation is always "forwards". Mar 24, 2013 at 23:37
  • also, tText cs = ($ cs) $ someFun >>> lines >>> map (drop 4) >>> reverse
    – Will Ness
    Mar 26, 2013 at 18:37

4 Answers 4

16

No, there isn't anything in a standard library that I know of. Years and years ago a lot of my code imported my breif but handy Forwards module:

> module Forwards where

> infixl 0 |>
> infixl 9 .>

> (|>) = flip ($)
> (.>) = flip (.)

I even used the same name as you!

These days I don't use it much at all - I got used to the order that function composition uses.

Feel free to use your own handy shortcuts.

I also use $ less than I used to. Where I used to write

thing = this $ that arg $ an other $ it

Now I write

thing = this . that arg . an other $ it
12

The lens library defines this operator as &.

1
  • 1
    And.. diagrams defines it as #.
    – Peter Hall
    Mar 24, 2013 at 22:41
7

You can also define (|>) as "flip id", and understanding why this works is a great lesson in type inference by unification as used in Haskell.

0

As far as my experience goes, I don't know any such library. And if such a library exists, I'd advise against using it.


Unless you are using the lens package, I'd suggest not to use externally defined operators of that kind. (In case of that lens package, you really need and already have such an operator.)

In my experience, IMHO and such ...

In cases where the readability enhances with a forward composition in contrast to the usual composition (not only when dealing with lenses), it is beneficial to define a special operator in that module or locally via let or where. For that, I tend to use single unicode symbols rather than ascii combos.

(·) = flip (.)
infixl 1 (·)

(§) = ($) -- left associative, no flip
infixl 0 (§)

Some years ago(, when there were no lenses), I thought of defining my own module for these, too. But then I grow to use that module sooo infrequent that I tended to reinvent the wheel anyway. To have these operators in a library may even increase the effort of reading the code: The reader has to look those rarely used operators up. In that case, locally defined operators are way better.

0

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.