In this expression, x is supposed to be 1 unit larger than n. However, the resulting list is made of mostly negative numbers.
f :: [Integer]
f = [x-n | x <- [1,2..], n <- [0,1..]]
Output from take 10 f
:
[1,0,-1,-2,-3,-4,-5,-6,-7,-8]
I expected it to be a list of 1s and I am not sure why that is not the case.
Thanks.
CodePudding user response:
In your definition, for each value of x
every value of n
is paired with it. For example consider
g :: [Integer]
g = [ (x, n) | x <- [1,2..4], n <- [0,1..3]]
The output is
[(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3),(3,0),(3,1),(3,2),(3,3),(4,0),(4,1),(4,2),(4,3)]
If you wanted the elements of x
and n
to be paired off by their respective positions then try zip
:
f1 = [x-n | (x, n) <- zip [1,2..] [0,1..]]
> take 10 f1
[1,1,1,1,1,1,1,1,1,1]
CodePudding user response:
As @Willem Van Onsen mentions in the comments, your comprehension amounts to a nested loop, where the outer loop on x never moves to the next iteration. What you are seeing is thus (1 - n) for each value of n.
What you seem to need is to zip the two lists together, and then do your subtraction, like so:
f = map (\x -> (fst x) - snd x) $ zip [1,2..] [0,1..]
This will take the elements from each list pairwise and do the subtraction to give an answer of 1 as you expect.
CodePudding user response:
The code you give
f :: [Integer]
f = [x-n | x <- [1,2..], n <- [0,1..]]
is the imperative equivalent to
for x in range(1, inf):
for n in range(0, inf):
return x - n
so clearly, x
is 1
at first, then it loops for n
all the way up to infinity. So you get 1 - 0
, 1 - 1
, 1 - 2
, etc...
From your question I guess you want to pair elements from each list one by one instead of a nested loop. Hence, the code should be
zipWith (-) [1..] [0..] -- this is equal to the infinite list [1,1,1,1,...]