Понимание списка Хаскелла, создание/расширение списка кортежей

#haskell

Вопрос:

Я пытаюсь создать компактные правила обновления для списка кортежей.

Это пример правила обновления:

 rule1: [(a,b) | (a,b) <- zip [1..3] [2..4]]
λ:[(1,2),(2,3),(3,4)]
 

Чего я хочу:

 rule2: [(a,b) (b,a) | (a,b) <- zip [1..3] [2..4]]
λ(expected):[(1,2),(2,1),(2,3),(3,2),(3,4),(4,3)]
 

Возможно ли что-то подобное в понимании списка Хаскелла?


Возможное решение, которое работает, но я нахожу его немного уродливым, — это:

 concat [[(a,b),(b,a)] | (a,b) <- zip [1..3] [2..4]]
λ: [(1,2),(2,1),(2,3),(3,2),(3,4),(4,3)]
 

Комментарии:

1. Важен ли порядок результата?

Ответ №1:

Во-первых , в вашем rule1 случае вам вообще не нужно понимание списка. Результатом zip уже является список кортежей, которые вы хотите:

 rule1 = zip [1..3] [2..4]
 

Для rule2 , однако, вы можете просто использовать два вложенных генератора, второй из которых является производным от каждого элемента первого, как это:

 rule2 = [p | (a, b) <- zip [1..3] [2..4], p <- [(a, b), (b, a)]]
 

Или, в качестве альтернативы, без деструкции кортежей, используя swap вместо этого:

 rule2 = [p | p0 <- zip [1..3] [2..4], p <- [p0, swap p0]]