2

List1 = [a,b]

List2 = [1,2]

I want the result list to look like this [a1, b2]

Currently i have:

[(v,a) | v <- List1, a <- List2 ]

but that gives [a1, a2, b1, b2]

3 Answers 3

6

What you need is zip :: [a] -> [b] -> [(a, b)]. This iterates concurrently over the two lists, and makes 2-tuples for these items.

For example:

Prelude> zip ['a', 'b'] [1,2] [('a',1),('b',2)] Prelude> zip [1,4,2,5] "bacd" [(1,'b'),(4,'a'),(2,'c'),(5,'d')] 

zip will stop from the moment that one of the two lists is exhausted. So if one of the lists is infinite, and the other is finite, then the result will be a finite list for example.

You can also make use of the ParallelListComp extension to iterate over collections in parallel in a list comprehension expression:

{-# LANGUAGE ParallelListComp #-} myzip :: [a] -> [b] -> [(a, b)] myzip la lb = [(a, b) | a <- la | b <- lb ]

but here it does not make much sense to do that. If you want to do more "complex" zipping, then this extension is probably more useful.

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

Comments

3

So, you want a function of type [Char] -> [Int] -> [(Char, Int)]. Let me introduce you to Hoogle:

zip :: [a] -> [b] -> [(a, b)] base Prelude Data.List GHC.List GHC.OldList, Cabal Distribution.Compat.Prelude.Internal, ghc GhcPrelude . zip takes two lists and returns a list of corresponding pairs. zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')] If one input list is short, excess elements of the longer list are discarded: zip [1] ['a', 'b'] = [(1, 'a')] zip [1, 2] ['a'] = [(1, 'a')] zip is right-lazy: zip [] _|_ = [] zip _|_ [] = _|_ zip is capable of list fusion, but it is restricted to its first list argument and its resulting list. zip :: () => [a] -> [b] -> [(a, b)] hspec Test.Hspec.Discover, base-compat Prelude.Compat, protolude Protolude, rio RIO.List RIO.Prelude, universum Universum.List.Reexport, dimensional Numeric.Units.Dimensional.Prelude, rebase Rebase.Prelude, ghc-lib-parser GhcPrelude, xmonad-contrib XMonad.Config.Prime, stack Stack.Prelude, LambdaHack Game.LambdaHack.Core.Prelude Game.LambdaHack.Core.Prelude, mixed-types-num Numeric.MixedTypes.PreludeHiding, heart-core Heart.Core.Prelude, intro Intro, hledger-web Hledger.Web.Import, tonalude Tonalude, brittany Language.Haskell.Brittany.Internal.Prelude zip takes two lists and returns a list of corresponding pairs. zip [1, 2] ['a', 'b'] = [(1, 'a'), (2, 'b')] If one input list is short, excess elements of the longer list are discarded: zip [1] ['a', 'b'] = [(1, 'a')] zip [1, 2] ['a'] = [(1, 'a')] zip is right-lazy: zip [] _|_ = [] zip _|_ [] = _|_ zipExact :: Partial => [a] -> [b] -> [(a, b)] safe Safe.Exact zipExact xs ys = | length xs == length ys = zip xs ys | otherwise = error "some message" zip :: () => [a] -> [b] -> [(a, b)] numeric-prelude NumericPrelude NumericPrelude.Base, distribution-opensuse OpenSuse.Prelude zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded. zip is right-lazy: zip [] _|_ = [] (+*+) :: [a] -> [b] -> [(a, b)] universe-base Data.Universe.Helpers cartesianProduct (,) ... 

The first hit

Comments

1

One other way can also be achieved by the ZipList type which is defined in Control.Applicative to lower the undeterministic approach to a simpler one to one mapping for the List types.

All you need is to import Control.Applicative and use the ZipList data constructor.

λ> getZipList $ (,) <$> ZipList "ab" <*> ZipList [1,2] [('a',1),('b',2)] 

getZipList is an accessor which extracts a proper list from the ZipList type.

4 Comments

Or even, with -XOverloadedLists, getZipList $ (,) <$> ['a','b'] <*> [1,2]. (Requires a very recent GHC (base>=4.15).) But... why not just use zip?
@leftaroundabout Interesting.. Sadly i still have base @ 4.13 so can't see that...
@leftaroundabout But... why not just use zip? Well especially with that valuable piece of information that you have just provided it simply has the potential to render zip and zipWith obselete yielding a more functional code.
@Redu doubtful. Most of the lists I zip are not lierals, but have type [a] from other computations. OverloadedLists is not a huge help in these situations.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.