Is there a function in Prelude to pair a value with that value applied to a function?
Asked Answered
G

2

6

I am searching for a function which looks something similar to this:

withSelf :: (a -> b) -> a -> (a, b) withSelf f x = (x, f x)

I have searched with Hoogle for such a function; I searched for (a -> b) -> a -> (a, b) and a -> (a -> b) -> (a, b), neither of which were conclusive. The Hackage page on Data.Tuple doesn't have what I'm looking for either.

I'm aware that it's trivial to write, but I want to write idiomatic Haskell where possible, and avoid re-inventing the wheel.

Guyton answered 29/3, 2015 at 17:15 Comment(2)
Hayoo will find some: hayoo.fh-wedel.de/?query=%28a+-%3E+b%29+-%3E+a+-%3E+%28a%2Cb%29 but I doubt that those are more idiomatic (if you have to fetch those libs just for this) than redefining it quick and easyChinch
One of the nice things about very polymorphic functions like this in a language like Haskell is that there's basically only one way to define a function with type (a -> b) -> a -> (a, b). So in a sense you don't have to worry about reinventing wheels like this; the type system forces your wheel to be just as good as anyone else's! ;)Agouti
G
7

The section (id &&&) does what you want:

> import Control.Arrow
> :t (id &&&)
(id &&&) :: (a -> c') -> a -> (a, c')
> (id &&&) succ 4
(4,5)
Gallonage answered 29/3, 2015 at 17:30 Comment(6)
I knew when I read the question that the answer would be in Control.Arrow, but I can never, ever remember what the different functions in there do.Guarantee
I like this answer - although I hope I will never see something like this in real code ;) (to the uninitiated (noob) eye (like mine) \f a -> (a, f a) is just easier to read)Chinch
@Guarantee well I guess you are right - the big question is: is this a good thing? - but I guess this is not the right place for such discussions and you already got my upvote too - so have a nice dayChinch
@CarstenKönig Indeed, I think I'm more likely to use the plain version in real code. The step from point-free to point-less can be very short.Gallonage
Thanks, I'm relatively new to Haskell and its control structures, so I'll take a look at Control.Arrow now.Guyton
@Quackmatic If you are new, keep in mind that arrows are quite abstract. You may want to look at functors and/or monads first.Gallonage
G
7

If you don't want to use Control.Arrow, you can always use Applicative:

withSelf f = (,) <$> id <*> f

Many people will probably actually understand this immediately, but for something so simple it's pretty silly.

Edit

As pointed out in a comment, this can be written even more briefly as

withSelf = ((,) <*>)

This astonished me at first, but it's actually very simple: for (->) r, fmap = (.), so the <$> id is completely redundant!

Guarantee answered 29/3, 2015 at 17:45 Comment(3)
Compared to the obvious definition this is ridiculously complex. :)Collettecolletti
It's simply withSelf = ((,) <*>)Dogmatics
ap (,) is shorter :)Purlieu

© 2022 - 2024 — McMap. All rights reserved.