问题
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?
回答1:
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 writef $ x $ y
1) now, with right associative
($)
, we can writef . g . h $ x
asf $ 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 off $! 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
回答2:
It's to mirror the fixity of $
. You could make a very good case for both $
and $!
having the wrong fixity.
来源:https://stackoverflow.com/questions/23570501/why-is-the-operator-right-associative