Список-оценка понимания - PullRequest
1 голос
/ 05 марта 2011

Я не понимаю, почему ниже 2 дело обстоит иначе? из-за ленивых оценок?

1)

Main> [x:xs | x:xs <- tails [1,2,3]]
=> [[1,2,3], [2,3], [3]]

2)

Main> [x:xs | x:xs' <- tails [1,2,3], x':xs <- tails [1,2,3]]
=> [[1,2,3],[1,3],[1], [2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]

Ответы [ 3 ]

2 голосов
/ 05 марта 2011

Они разные по определению. Лучший способ показать это - пример. Понимания списка пытаются найти все возможные наборы переменных, которые могут быть выбраны из списка без нарушения условия. Если у вас более одной переменной, она возвращает каждую их комбинацию. Например:

[(x,y) | x <- [1,2,3], y <- [1,2,3]]

Выходы:

[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]

Что мы можем увидеть? Сначала выбирается элемент первого списка, чем один из второго списка. В результате получается список всех возможных способов выбора x и y .

Так что ваше второе утверждение, конечно, должно дать второй результат.

1 голос
/ 05 марта 2011

Нет, это не имеет ничего общего с ленивой оценкой.

Рассмотрим третий случай:

Prelude Data.List> [x:xs | x:xs' <- tails [1,2,3], x':xs <- tails [1,2,3], x == x']
[[1,2,3],[2,3],[3]]
0 голосов
/ 05 марта 2011

Еще один взгляд на это:

ghci> :m +Data.List
ghci> :m +Control.Applicative
ghci> let l1 = [x | x:xs <- tails [1,2,3]]
ghci> l1
[1,2,3]
ghci> let l2 = [xs | x:xs <- tails [1,2,3]]
ghci> l2
[[2,3],[3],[]]

Ваше первое понимание рисует x и xs как «пару», что-то вроде того, что они держатся «застегнутыми» вместе.

ghci> zipWith (:) l1 l2
[[1,2,3],[2,3],[3]]

Ваше второе понимание рисует все комбинации x и xs, комбинируя их с (:).

ghci> (:) <$> l1 <*> l2
[[1,2,3],[1,3],[1],[2,2,3],[2,3],[2],[3,2,3],[3,3],[3]]
...