It's not lazy, it returns iterator. There is a difference, you can't slice or index its result anymore. Compare to Clojure or Haskell map, which are truly lazy.
m = map(lambda x: x*2, range(100000000000000000000))
i = itertools.islice(m, 10**6, None)
next(i)
Somewhat equivalent? This does seem a little slow calculating the first million squares, but subsequent calls to next(i) are snappy(ish).I'm not sure how close you could get to "truly" lazy sequences combining count, zip and slice, though.
It's not represented in head normal form, but it's still lazy.
The limitations you mentioned are not an artifact of the implementation being eager(because it's not eager), but instead are an artifact of the representation used.
(fmap a function anArray) `get` n
?How does fmap construct its value?