extra
extra copied to clipboard
Add flip const
Sometimes you want the function which takes two arguments and ignores the first. You can write that as:
flip const
\_ x -> x
const id
\_ -> id
Assuming that thing is called f, and we pass around a WHNF f x, the first two of those will leave the x captured. But in my view, the first two are also clearer to read. I however, don't guarantee that's true, my reasoning may be wrong....
It seems like having a flipConst or other function might be useful, with the best space behaviour it can do? Or maybe the restriction to only after people seq a function is just not helpful? Is there a good name for this function? Do lambdas really reduce differently for \x y -> ... vs \x -> \y -> ...? Or does the id make it different?
CC @josephcsible who brought this up first in HLint.
AFAIK, of all the possibilities in your post, only flip const has the problem I described, and all of the other combinations will be fine.
flip = \f x y -> f y x
const = \x _ -> x
f = flip const
f = (\f x y -> f y x) (\x _ -> x)
I guess I don't see what makes that special. But certainly have no confidence that it isn't.
Looks like your 4th line has a typo: it should be f = (\f x y -> f y x) (\x _ -> x). Anyway, the performance problem stems from flip. When you do flip f x, no matter what f is, x sticks around until the expression gets one more parameter. Your other cases are all fine because they don't use flip or any equivalent to it.
I don't see why the 3rd line is a problem, but the 4th line isn't. The 4th line uses an inlined version of flip, so I don't see why it isn't equivalent.
After a beta-reduction, f = (\f x y -> f y x) (\x _ -> x) becomes f = (\x y -> (\x _ -> x) y x). Now pass someBigThing to that, and you get (\y -> (\x _ -> x) y someBigThing). This is now equivalent to the identity function, but it unnecessarily references someBigThing.
So both definitions of f have a problem? That I understand, but wasn't my understanding of your statement.
Hmm, or maybe I have come back to this thread after too long away. I'll have a reread in the morning when I'm more fresh.
So both definitions of f have a problem? That I understand, but wasn't my understanding of your statement.
I realize I was a bit unclear. These are fine:
\_ x -> x
const id
\_ -> id
And these are bad:
flip const
(\f x y -> f y x) (\x _ -> x)
Cool, I follow now. Given it's so easy to get this wrong, I'm thinking a function that is morally flip const, but without the space leak, would be a great addition. Only question is what to name it - flipConst is nice and obvious, but maybe there's a better name someone can think of.