5

I'm just learning Haskell and I'm still not entirely clear on when and how strict evaluation is forced

When I want a function to evaluate its arguments strictly I find myself writing

((f $! x) $! y ) $! z

which seems weird. Shouldn't $! be left-associative so I could write

f $! x $! y $! z

and have it do what I want?

Am I completely misunderstanding the $! operator?

dspyz
  • 5,280
  • 2
  • 25
  • 63
  • 1
    Why not just write a function `!$` with the reversed fixity of `$!` that does what you want? – bheklilr May 09 '14 at 17:30
  • 1
    The question is why the function isn't already defined that way. I want to know if my desire to write it that way reflects a misunderstanding of how things in Haskell work. – dspyz May 09 '14 at 17:33
  • 3
    If you're just learning Haskell I don't think you should be messing with strict application. It's very rarely needed. – augustss May 09 '14 at 18:07

2 Answers2

11

It's to mirror the fixity of $. You could make a very good case for both $ and $! having the wrong fixity.

augustss
  • 22,884
  • 5
  • 56
  • 93
  • What is $? I googled "haskell operators" but none of the first couple google links mention it (even the one that's a PDF file containing a list of haskell operators). Neither has the book I'm reading mentioned it so far (Real World Haskell). Is there a list of all Haskell operators somewhere? – dspyz May 09 '14 at 17:31
  • 1
    @dspyz http://stackoverflow.com/questions/940382/haskell-difference-between-dot-and-dollar-sign/1290727#1290727 – Thomas M. DuBuisson May 09 '14 at 17:39
  • @dspyz You'll even find a [link to the author of Real World Haskell commenting on its use in the book](http://stackoverflow.com/questions/3030675/haskell-function-composition-and-function-application-idioms-correct-us) in Thomas' comment. – bheklilr May 09 '14 at 17:41
  • Sorry, I should ask my questions one at a time. Where can I find a list of Haskell operators? – dspyz May 09 '14 at 17:46
  • 1
    The Prelude operators are in the [Haskell report](http://www.haskell.org/onlinereport/decls.html#prelude-fixities). – augustss May 09 '14 at 18:06
  • 1
    @dspyz Do note that there's no such thing as a list of Haskell operators. Is `*%^*%^*&&$&%^` a Haskell operator? Well, it could be, if some library defined it. – Carl May 09 '14 at 19:24
  • Sorry, I meant pre-defined operators – dspyz May 09 '14 at 19:49
  • 1
    @dspyz To search for Haskell operators and functions by name try [Hoogle](http://www.haskell.org/hoogle/) (uses a limited set of packages, but can also search by type which is very useful) or [Hayoo](http://holumbus.fh-wedel.de/hayoo/hayoo.html) (searches only by name, but in all of Hackage.) – Ørjan Johansen May 09 '14 at 21:01
  • 3
    @dspyz FP Complete's Hoogle searches a larger number of packages than the regular Hoogle, so it can be handy https://www.fpcomplete.com/hoogle – David Young May 09 '14 at 23:54
7

Argument against

I found a proposal from 2008 in haskell-prime to make the $ and $! operators left-associative:

https://ghc.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity

There is only one argument against the proposal: "This would break a lot of code".

Arguments in favour

Instead, there are given four arguments in favour of left-associative ($), the last one being the same as yours, and considered the most important. They are, in short:

  • 0) given the expression f x y, with two applications, we would be able to write f $ x $ y

  • 1) now, with right associative ($), we can write f . g . h $ x as f $ g $ h $ x,

    however: \x -> f $ g $ h $ x ==> f $ g $ h is invalid,

    so that writing such pipelines with composition is better, as it allows easier cleanup of code

  • 2) Left associative ($) allows you to eliminate more parentheses, in addition to the ones eliminated with (.), for instance:

    f (g x) (h y) ==> f $ g x $ h y

  • 3) your argument: the right associative version of $! is inconvenient because of giving rise to things like: ((f $! x) $! y) $! z instead of f $! x $! y $! z

Conclusion

I give support to use the better left-associative version of application operators redefining them at the beginning of our code, like this:

import Prelude hiding (($), ($!))

infixl 0  $, $!
($), ($!) :: (a -> b) -> a -> b  
f $  x =         f x
f $! x = x `seq` f x
enrique
  • 492
  • 3
  • 11
  • 2
    Older (2006), similar discussion in Haskell Cafe (he tells: "the associativity of $ is just plain wrong"): http://www.mail-archive.com/haskell-cafe@haskell.org/msg12549.html – enrique Dec 25 '14 at 21:38
  • To translate an expression in the conventional style `f $! g $! x` with the cited tactic for plain `$` , one would need some sort of strict composition: `f .! g $! x`. I wonder: is there such operator already defined in a library? – imz -- Ivan Zakharyaschev Jun 18 '15 at 08:31
  • BTW, the current `<$>` is consistent with the current conventional `$`: `f <$> g <$> x` seems to be equivalent to `f . g <$> x`. But another, left-associative version of `<$>` wouldn't make much sense, because consuming several Applicative arguments is written as `f <$> x <*> y` or `g <*> x <*> y` (for a pure `f` or an Applicative `g`). It seems that `<*>` is already left-associative (as wanted for `$` in Haskell-prime), and lower priority than `<$>`. – imz -- Ivan Zakharyaschev Jun 18 '15 at 08:49
  • It seems that `<$>` is left-associative [in the latest base](http://hackage.haskell.org/package/base-4.8.0.0/docs/Control-Applicative.html#v:-60--36--62-) (so, inconsistent with the conventional `$`), contrary to what I said in the above comment. But my `<$>` from an older base I have on my system is right associative! (`show <$> show <$> Just 3` gives `Just "\"3\""` for me; or [I don't understand what is happening, so I asked a question](http://stackoverflow.com/q/30911093/94687)) – imz -- Ivan Zakharyaschev Jun 18 '15 at 09:12
  • Yes, there exists `(.!)`: [Strict composition](https://hackage.haskell.org/package/pointless-fun-1.1.0.1/docs/Data-Function-Pointless.html#g:3). – imz -- Ivan Zakharyaschev Jun 23 '15 at 08:17