Reputation: 367
I would like to transform the following tuple list
a = [(1,()),(2,())]
into a nested tuple list by the same value
b = [(False,(1,())),(False,(2,()))]
Using the zip function in this format
zip [False] a
only gives me
[(False,(1,()))]
Any suggestions or advice would be much appreciated.
Upvotes: 16
Views: 1814
Reputation: 39654
In addition to others answers it is also possible to write a generic function for any Functor
, not just for lists:
strengthL :: Functor f => a -> f b -> f (a, b)
strengthL = fmap . (,)
strengthR :: Functor f => a -> f b -> f (b, a)
strengthR = fmap . flip (,)
Then strengthL
can be applied to False and the original list:
Prelude> strengthL False [(1,()),(2,())]
[(False,(1,())),(False,(2,()))]
Upvotes: 6
Reputation: 54078
Alternatively, instead of using zip
you can use map
:
map (\x -> (False, x)) a
This would more appropriately express your intent (in my opinion) since you want to do the same thing to every element of the list. If you want to do different things to each element, then zip
or zipWith
may be more appropriate.
If you wanted to avoid the lambda, you can write it pointfree using &&&
from Control.Arrow
:
map (const False &&& id) a
which basically says "apply the functions const False
and id
to the input, then construct a tuple of both of their outputs". There is the TupleSections
extension which would allow you to write this as
map (False,) a
(tip provided by @thoferon), but I personally find this less clear, since you have to know that the extension is enabled and notice the ,
after False
. You could write it as
map ((,) False) a
without the extension since (,)
acts as a function of type a -> b -> (a, b)
, and while a bit more verbose it doesn't require enabling a language extension.
Upvotes: 29
Reputation: 62868
If you zip two lists of different lengths, you get the length of the shortest list.
You can fix this by zipping against an infinitely long list:
zip (repeat False) a
should do the trick.
Upvotes: 33