9

I have a lambda \x f -> f x that is being used in a foldM operation, where x is a value and f :: a -> b.

Is there a built-in function that does this?

Can I replace

foldM (\x f -> f x) ...

with some f'

foldM f' ...

I thought that flip would do this, but it takes three arguments (flip :: (a -> b -> c) -> b -> a -> c)

It is probably similar to |> in F#.

2 Answers 2

22

You can use flip id or flip ($) (as ($) is just a special id for functions):

Prelude> flip id 3 (+2)
5
Prelude> flip ($) 7 (>10)
False

This is an interesting use of partial application: id f x with f being a function is just f x. Obviously, this is also the same as (flip id) x f, so flip id is the function you are looking for.

If you feel adventurous, try inferring the type of flip id or flip ($) manually. It's fun :)

Sign up to request clarification or add additional context in comments.

9 Comments

Wow, that took me about 5 minutes with paper and pen to work out how id's a -> a signature could somehow map onto flip's expecting something with a -> b -> c. It might be worth going into that a little bit!
@Len: It becomes clearer once you see that when applied to functions, id is the same as ($)
That's very true! The "a-ha" moment for me was realising that I should see a -> b -> c as the a -> (b -> c) that it is, and then matched that to id's a' -> a' and found that a = a' = (b -> c)—I was looking too much at the differences in arity and couldn't get past it.
Thanks. Haskell is a cool language, but I feel like my brain is in a maze of twisty little passages, all alike ...
@Ralph: There's also pointfree package on Hackage. cabal install pointfree and pointfree "\a b -> b a".
|
8

Yes, it's called flip :: (a -> b -> c) -> b -> a -> c, e.g. flip (>) 3 5 == True. More infos and source on hackage: flip.

What you want is simply to reverse the arguments of function application, right? Well, since ($) is function application, by using flip you may write flip ($) :: b -> (b -> c) -> c. Let see what happens. Here is the source for the two prelude functions:

-- from Hackage:
($)                     :: (a -> b) -> a -> b
f $ x                   =  f x

-- from Hackage:
flip                    :: (a -> b -> c) -> b -> a -> c
flip f x y              =  f y x

So, basically if you put together the types, flip ($) becomes

flip ($) :: 
  b        ->    -- type of x, argument of y and second argument of ($)
  (b -> c) ->    -- type of y, function applied by ($) as its first argument
  c        ->    -- result of the application "y x"

If you follow the actual definitions of the functions:

flip ($) = (\f x y -> f y x) ($)    -- from flip's def.
         = \x y -> ($) y x          -- partial application
         = y x                      -- from ($)'s def.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.