2016-05-08 1 views
1

Один из вопросов, которые пришли в одной из моих лекций был следующим:Haskell точка точка обозначения в списке - неожиданный выход

trips :: [(Int, Int, Int)] 
trips = [ (x,y,z) | z <- [2..], y <- [2..z-1], x <- [2..y-1] ] 

What is the first five elements output? 

Теперь я думал, что я знал, как точка точка обозначения работала, но когда я поставите вышеуказанное в компилятор, выход:

(2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5), (2, 3) , 6) и т. Д.

Как это происходит?

Я думал, что если все началось с [2 ..], то все последующие списки начнутся с двух? z определяется как [2 ..], но он никогда не отображает 2 как третий int. Я, очевидно, что-то пропустил, но я не совсем уверен, что.

+1

Представьте, что это как петля, которая увеличивает свое гнездование слева направо. – ThreeFx

ответ

6
[ (x,y,z) | z <- [2..], y <- [2..z-1], x <- [2..y-1] ] = 
[ (x,y,2) | y <- [2..2-1], x <- [2..y-1] ] ++ 
[ (x,y,3) | y <- [2..3-1], x <- [2..y-1] ] ++ 
[ (x,y,4) | y <- [2..4-1], x <- [2..y-1] ] ++ 
... = 
[ (x,y,2) | y <- [2..1], x <- [2..y-1] ] ++ 
[ (x,y,3) | y <- [2..2], x <- [2..y-1] ] ++ 
[ (x,y,4) | y <- [2..3], x <- [2..y-1] ] ++ 
... = 
[ (x,y,2) | y <- [], x <- [2..y-1] ] ++ 
[ (x,y,3) | y <- [2], x <- [2..y-1] ] ++ 
[ (x,y,4) | y <- [2,3], x <- [2..y-1] ] ++ 
... 

Обратите внимание диапазон y <- [2..2-1] т.е. y <- [2..1] т.е. y <- []. Из-за этого нет никаких тэлей (x,y,2) для генерации.

Точно так же, когда y является 2, диапазон z <- [2..y-1] не будет генерировать ничего, и мы не получаем троек вида (x,2,3).

Смежные вопросы