简体   繁体   中英

Is it possible to map tuple of functions over a list in Haskell?

I'm trying to do find a way to do something like this:

(head, last) `someFunction` [1, 2, 3]

to produce the tuple (1, 3) as output.

It seems similar in theory to an applicative functor, but a little backwards. I'm guessing there's a similar function that does this (or some way to make one), but I can't seem to find it/figure it out.

I tried defining a function like this:

fmap' :: ((a -> b), (a -> b)) -> [a] -> (b, b)
fmap' (f1, f2) xs = (f1 xs, f2 xs)

but GHC won't actually compile this.

Any help would be great; thanks!

Edit (a whole year later!):

My fmap' wouldn't compile because the type signature was wrong. Obviously there are better ways to do what I was doing, but the type of my fmap' should instead be:

fmap' :: ((a -> b), (a -> b)) -> a -> (b, b)

In that case, it compiles and runs just fine.

I think you can do this with arrows.

head &&& last $ [1,2,3]

will return (1,3) .

It seems similar in theory to an applicative functor, but a little backwards.

Actually, it's a boring old forwards applicative functor; specifically, the reader ((->) r) .

Prelude Control.Applicative> liftA2 (,) head last [1,2,3]
(1,3)

Or, if you're into that kind of thing:

Prelude Control.Applicative> let sequenceA [] = pure []; sequenceA (x:xs) = (:) <$> x <*> sequenceA xs
Prelude Control.Applicative> [head, last] `sequenceA` [1,2,3]
[1,3]

The type of fmap' is wrong. It should be

fmap' :: ([a] -> b, [a] -> b) -> [a] -> (b, b)

or, it can be more generalized

fmap' :: (a -> b, a -> c) -> a -> (b, c)

It doesn't really resemble fmap :: (a -> b) -> fa -> fb .

Something to try in this situation is to omit the type signature and check what GHC infers.

Doing so and asking GHCi :t fmap' yields the signature

fmap' :: (t2 -> t, t2 -> t1) -> t2 -> (t, t1)

which is identical to KennyTM's generalized version, and will give you the behaviour you're looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM