[x:ys | x<-[1,2], ys<-[]]
above code outputs []
. I thought it should output [1,2]
.
So what am I get wrong with Haskell evaluation?
[x:ys | x<-[1,2], ys<-[]]
above code outputs []
. I thought it should output [1,2]
.
So what am I get wrong with Haskell evaluation?
There are two problems with your expectation:
x:ys
always creates a new list; x:[] == [x]
, not x:[] == x
.x:[] == x
, the fact remains that ys <- []
does not assign the name ys
to the empty list; it assigns ys
to a value contained in the empty list (and of course, there is no such value to assign to ys
).You could change ys <- []
to ys <- [[]]
, in which case you would get
> [x:ys | x<-[1,2], ys<-[[]]]
[[1], [2]]
but if you want [1,2]
, the trivial list comprehension would simply be
> [x | x <- [1,2]]
[1,2]
with no other list involved, because you don't want a list of lists as your answer.
List comprehensions express nested loops:
[x:ys | x<-[1,2], ys<-[]]
==
do { x<-[1,2] ; do { ys<-[] ; return (x:ys) } }
==
{ for each x in [1,2]: { for each ys in []: yield (x:ys) } }
==
{ { for each ys in []: yield (1:ys) }
; { for each ys in []: yield (2:ys) }
}
==
{ { for none: yield ... } ; { for none: yield ... } }
==
{ none ; none }
==
none.
This is reminiscent of matrix multiplication:
join [ {- for 1: -} [ a,b,c ], [ 1a, 1b, 1c,
{- for 2: -} [ d,e ], = 2d, 2e,
{- for 3: -} [ f,g,h,i ], 3f, 3g, 3h, 3i
] ]
Thus if the list produced for each element of the first list is empty, the total list is empty as well, because concat [ [], [], [] ] == []
.