0

So, been going over some old exams in preparation for my upcoming one and came across this question:

Write Haskell code to define ints :: [Int] an infinite list of the following form: [0, 1, -1, 2, -2, 3, -3, 4, -4..]

I've been plugging at it for the past half an hour but can't seem to find anything to solve it or that will do what I want. I get the feeling that what I am really wanting is a list comprehension of the form

ints :: [Int]
ints = [0] ++ [x (-x) | x <- [1..]]

But this doesn't work and I'm unsure of how to get it to work

Johannes Weiss
  • 52,533
  • 16
  • 102
  • 136
Syzorr
  • 587
  • 1
  • 5
  • 17
  • 1
    `x` is a number, not a function... – AJF Jun 10 '15 at 11:44
  • See also the [universe](http://hackage.haskell.org/package/universe) package, which provides `ints` under the name `universe`, and for many types, not just `Int`. The ordering for `Integer` matches the ordering given here (though not the one for `Int`); and I bet you want `Integer` anyway, since you claim you want an infinite list, which `ints` is not. – Daniel Wagner Jun 10 '15 at 18:28

1 Answers1

6

The problem is that x (-x) is not of type Int (thanks to @leftaroundabout removed non-sense about non-valid syntax here). You want to generate two values for every x. So I guess the easiest way is to create lots of list pairs [1, -1], [2, -2], ... and then to concatenate them all together. And obviously prepend a 0.

ints :: [Int]
ints = 0 : concat [[x, (-x)] | x <- [1..]]

Also, you might want to use Integer instead of Int as Int will overflow at some point but Integer won't.

Johannes Weiss
  • 52,533
  • 16
  • 102
  • 136
  • 3
    Alternatively, with a right fold: `ints = 0 : foldr (\n ns -> n : -n : ns) [] [1 ..]`. – jub0bs Jun 10 '15 at 11:40
  • 1
    indeed, sticked with list comprehension as that was what OP used but actually prefer the right fold. – Johannes Weiss Jun 10 '15 at 11:42
  • 6
    Or maybe `ints = 0 : ([1..] >>= \x -> [x, -x])` . – AJF Jun 10 '15 at 11:45
  • @AJFarmar Beat me to it by one minute. – Sebastian Redl Jun 10 '15 at 11:46
  • @AJFarmar Ah yes, using the list monad. Nice. – jub0bs Jun 10 '15 at 11:46
  • 2
    Actually, `x (-x)` _is_ valid syntax, it just doesn't make much sense type-wise (since `x` has to be both a function and a number). – leftaroundabout Jun 10 '15 at 11:49
  • @leftaroundabout True; valid syntax and valid types are two *very* different things. – AJF Jun 10 '15 at 11:53
  • @leftaroundabout, it makes [some](http://stackoverflow.com/a/27665374/3237465) sense, actually. – effectfully Jun 10 '15 at 12:38
  • Note that the foldr version above is basically just `concatMap (\x -> [x,-x]) [1..]` - or `[1..] >>= (\x -> [x,-x])` if you prefer infix. – Cubic Jun 10 '15 at 14:27
  • 4
    Why use `concat` when you're already using a list comprehension? `ints = 0 : [v | x <- [1..], v <- [x, -x]]` – Daniel Wagner Jun 10 '15 at 18:28
  • I have really appreciated all these comments. I wasn't sure what was wrong with me when trying to figure this out but I kept trying various things that were close to what you guys have provided but not quite right and the many different ways given have really shown me a lot. – Syzorr Jun 10 '15 at 20:42