Reputation: 23
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]
Upvotes: 2
Views: 241
Reputation: 26161
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.
Upvotes: 1
Reputation: 476659
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.
Upvotes: 6
Reputation: 120711
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
Upvotes: 3