Haskell, 2 списка в список точечных кортежей - PullRequest
3 голосов
/ 06 мая 2020

List1 = [a,b]

List2 = [1,2]

Я хочу, чтобы список результатов выглядел так [a1, b2]

В настоящее время у меня есть:

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

, но это дает [a1, a2, b1, b2]

Ответы [ 3 ]

7 голосов
/ 06 мая 2020

Вам нужно zip :: [a] -> [b] -> [(a, b)]. Это выполняет итерацию одновременно по двум спискам и создает для этих элементов 2 кортежа.

Например:

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 остановится с момента, когда один из двух списков станет истощены. Таким образом, если один из списков бесконечен, а другой - конечен, то результатом будет, например, конечный список.

Вы также можете использовать ParallelListComp extension для параллельного перебора коллекций в выражении понимания списка:

{-# LANGUAGE <b>ParallelListComp</b> #-}

myzip :: [a] -> [b] -> [(a, b)]
myzip la lb = [(a, b) | a <- la | b <- lb ]

но здесь это не имеет особого смысла. Если вы хотите сделать более "сложное" архивирование, то это расширение, вероятно, будет более полезным.

3 голосов
/ 06 мая 2020

Итак, вам нужна функция типа [Char] -> [Int] -> [(Char, Int)]. Позвольте мне познакомить вас с Hoogle :

<a href="https://hackage.haskell.org/package/base/docs/Prelude.html#v:zip" rel="nofollow noreferrer">zip :: [a] -> [b] -> [(a, b)]</a>
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.
<a href="https://hackage.haskell.org/package/hspec/docs/Test-Hspec-Discover.html#v:zip" rel="nofollow noreferrer">zip :: () => [a] -> [b] -> [(a, b)]</a>
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 _|_ [] = _|_

<a href="https://hackage.haskell.org/package/safe/docs/Safe-Exact.html#v:zipExact" rel="nofollow noreferrer">zipExact :: Partial => [a] -> [b] -> [(a, b)]</a>
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 (,)
...

Первое обращение

1 голос
/ 06 мая 2020

Другой способ также может быть реализован с помощью типа ZipList, который определен в Control.Applicative, чтобы снизить неопределенность c подхода до более простого сопоставления один в один для типов List.

Все, что вам нужно, - это import Control.Applicative и использовать конструктор данных ZipList.

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

getZipList - это средство доступа, которое извлекает правильный список из типа ZipList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...