views:

295

answers:

4

Hello, I am an absolute newbie in Haskell yet trying to understand how it works.

I want to write my own lazy list of integers such as [1,2,3,4,5...].

For list of ones I have written

ones = 1 : ones

and when tried, works fine:

*Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]

How can I do the same for increasing integers ?

I have tried this but it indeed fails:

int  = 1 : head[ int + 1]

And after that how can I make a method that multiplies two streams? such as:

mulstream s1 s2 = head[s1] * head[s2] : mulstream [tail s1] [tail s2]
+13  A: 

The reasons that int = 1 : head [ int + 1] doesn't work are:

  • head returns a single element, but the second argument to : needs to be a list.
  • int + 1 tries to add a list and a number, which isn't possible.

The easiest way to create the list counting up from 1 to infinity is [1..]

To count in steps other than 1 you can use [firstElement, secondElement ..], e.g. to create a list of all positive odd integers: [1, 3 ..]

To get infinite lists of the form [x, f x, f (f x), f (f (f x)),...] you can use iterate f x, e.g. iterate (*2) 1 will return the list [1, 2, 4, 16,...].

To apply an operation pairwise on each pair of elements of two list, use zipWith:

mulstream s1 s2 = zipWith (*) s1 s2

To make this definition more concise you can use the point-free form:

mulstream = zipWith (*)
sepp2k
+4  A: 

For natural numbers you have to use map:

num1 = 1 : map (+1) num1

Or comprehensions:

num2 = 1 : [x+1 | x <- num2]

Or of course:

num3 = [1..]
Łukasz Lew
or also `nat = 1 : map succ nat`
jetxee
+1  A: 

There is syntax for this in the langauge:

take 10 [1,2..]

=> [1,2,3,4,5,6,7,8,9,10]

You can even do different strides:

take 10 [1,3..]
=> [1,3,5,7,9,11,13,15,17,19]
clord
+1  A: 

I'm not sure if this is what you were asking, but it would seem to me that you wanted to build a list of increasing natural numbers, without relying on any other list. So, by that token, you can do things like

incr a = a : inrc (a+1)
lst = inrc 1

take 3 lst
=> [1,2,3]

That, technically, is called an accumulating function (I believe) and then all we did is make a special case of it easily usable with 'lst'

You can go mad from there, doing things like:

lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a)

take 3 lst
=> [1,2,3]

and so on, though that probably relies on some stuff that you wont have learned yet (where) - judging by the OP - but it should still read pretty easily.

Oh, right, and then the list multiplication. Well, you can use zipWith (*) as mentioned above, or you could reinvent the wheel like this (it's more fun, trust me :)

lmul a b = (head a * head b) : lmul (tail a) (tail b) 
safemul a b = take (minimum [len a, len b]) (lmul a b)

The reason for safemul, I believe, you can find out by experimenting with the function, but it has to do with 'tail'. The trouble is, there's no case for an empty list, mismatched lists, and so on, so you're either going to have to hack together various definitions (lmul _ [] = []) or use guards and or where and so on ... or stick with zipWith :)

Hiato