Использование понимания списка с двумя переменными в haskell - PullRequest
0 голосов
/ 21 мая 2018

кто-нибудь знает, как я могу понять список с двумя переменными в haskell?

отл.

[ x * y  | x <- [1..10]  y <- [1..10]]

это должно привести к

[1,4,9,16,25,36,49,64,81,100]

, но на самом деле это приводит к ghci

<interactive>:13:23-24: error:
    parse error on input ‘<-’
    Perhaps this statement should be within a 'do' block?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

Здесь есть две проблемы: синтаксическая одна и семантическая одна.

На пути к правильному выражению понимания списка

Синтаксическим является то, что вы разделяете части понимания списка (это могут быть генераторы , фильтры и let предложения) с помощью запятой (,) :

[ x * y  | x <- [1..10]<b>,</b> y <- [1..10]]

Но теперь мы не получим желаемый результат.Действительно:

Prelude> [ x * y  | x <- [1..10], y <- [1..10]]
[1,2,3,4,5,6,7,8,9,10,2,4,6,8,10,12,14,16,18,20,3,6,9,12,15,18,21,24,27,30,4,8,12,16,20,24,28,32,36,40,5,10,15,20,25,30,35,40,45,50,6,12,18,24,30,36,42,48,54,60,7,14,21,28,35,42,49,56,63,70,8,16,24,32,40,48,56,64,72,80,9,18,27,36,45,54,63,72,81,90,10,20,30,40,50,60,70,80,90,100]

Здесь мы имеем все умножения между двумя целыми числами от 1 до 10.Поскольку для каждого x в списке [1..10], мы перебираем список [1..10] для y.Это, однако, не соответствует вашему запрошенному списку, поэтому возникает семантическая ошибка.

Получение списка квадратов

То, что вам нужно, это список всех квадратов чисел,В этом случае есть только одна переменная x, и для каждого значения x мы получаем x*x:

[ x * x  | x <- [1..10]]

, тогда это приводит к:

Prelude> [ x * x  | x <- [1..10]]
[1,4,9,16,25,36,49,64,81,100]

Параллельное перечисление списков

Если у вас есть два списка для параллельного перечисления, вы можете сделать это с помощью zip, например, если мы хотим умножить элементы [1..10] с элементами [5..14] поэлементно , мы можем сделать это с:

[ x * y  | (x, y) <- zip [1..10] [5..14]]
0 голосов
/ 21 мая 2018

Вам нужно сжать два диапазона вместе:

[ x * y | (x, y) <- zip [1..10] [1..10] ]

Вы можете иметь два отдельных итератора, разделенных запятой

[ x * y | x <- [1..10], y <-[1..10] ]

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

...