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]
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.
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
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.
-XOverloadedLists, getZipList $ (,) <$> ['a','b'] <*> [1,2]. (Requires a very recent GHC (base>=4.15).) But... why not just use zip?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.[a] from other computations. OverloadedLists is not a huge help in these situations.