Page 2 of 2

Posted: Sat Mar 17, 2007 2:26 pm
by ehird
Yes, pretty much. Except, you can do operations on that array like any normal array. Most of the functions in the Haskell Prelude are designed so that they work just fine on infinite arrays.

Posted: Sat Mar 17, 2007 6:30 pm
by mystran
The example of an infinite list of 1s is pretty boring one, since one can implement it in any language like this:

Code: Select all


struct list_of_int { int x; list_of_int * rest; }

list_of_int ones;

ones.x = 1;
ones.rest = &ones;
Because Haskell is pure (that is, no mutations) there is no way to tell the difference.

More interesting stuff can be done. Suppose you want an infinite list of squares (my syntax might be off since I don't know Haskell for real):

Code: Select all

square x = x * x

ints = [1, 2, 3 .. ]

map fn [] = []
map fn [x:xs] = [fn x : map fn xs]

squares = map square ints

Now map is AFAIK defined in prelude so I just included it for the fun of it.

Now, squares is an infinite list of squares, that is [1, 4, 9, 16 ... ] continuing as far as you care to look at it. :)

Also notice how it is possible to avoid explicit conditionals in many cases by relying on pattern matching instead. That is, the version of "map" is selected automatically based on whether second argument is empty or non-empty list.

Ofcourse there's easier way to write that in Haskell, because (AFAIK) you can just as well use so called list-comprehensions:

Code: Select all

squares = [ x * x | x <- [1, 2, 3 ..]]
That basicly says, "let squares be a list of those numbers which you get when you evaluate x*x drawing x from the list of [1, 2, 3 ..]"


Anyway.. the really interesting part of Haskell isn't really that it's lazy or allows list comprehensions, because both of those are pretty easy to implement:
- for lazy evaluation use promises and force them as required, caching values
- for comprehensions, just rewrite then in terms of map and filter (map defined above, filter looking something like:

Code: Select all

filter fn [] = []
filter fn [x:xs] = if fn x
                     then [x : filter fn xs]
                     else filter fn xs
The really interesting part of Haskell instead, is what the type system does for you....

Posted: Sun Mar 18, 2007 8:37 am
by ehird
Also, [..] is a syntax error:

Code: Select all

<ehird> > [1, 2, 3 .. ]
<lambdabot> Parse error
<ehird> > [1]
<lambdabot> [1]

Posted: Sun Mar 18, 2007 11:45 am
by mystran
ehird wrote:Also, [..] is a syntax error:

Code: Select all

<ehird> > [1, 2, 3 .. ]
<lambdabot> Parse error
<ehird> > [1]
<lambdabot> [1]
Would it work if one dropped the space? :D

Oh well, I warned about possibly having issues with syntax....

Posted: Sun Mar 18, 2007 12:37 pm
by ehird
[1, 2, 3..] still gives a parse error. :P

Posted: Sun Mar 18, 2007 1:25 pm
by mystran
Oh ok, I guess [1..] then, that should work, though I'd have preferred something more verbose for readability. Must have confused with some other similar language.

Haskell grammar is evil anyway... one of the things I dislike about the language.

Posted: Sun Mar 18, 2007 1:33 pm
by ehird

Code: Select all

[19:43] ehird: > [1..]
[19:43] lambdabot: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,
[19:43] lambdabot: 69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
[19:43] lambdabot: 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,
[19:43] lambdabot: 175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
[19:43] lambdabot: 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,
[19:43] lambdabot: [6 @more lines]
So it does something quite different ;)

Posted: Sun Mar 18, 2007 1:42 pm
by mystran
Isn't that exactly what we wanted?

Posted: Sun Mar 18, 2007 2:02 pm
by ehird
[1,2,3,4,succ ad-infinitum] != [1,1,1,1 ad-infinitum] :)

Posted: Mon Mar 19, 2007 11:12 am
by mystran
fnord

Posted: Mon Mar 19, 2007 3:45 pm
by Combuster
the main difference between languages is that some provide features by default that others dont. Lazy evaluation is haskell's feature. Any turing-complete language can be used to build programs with the same behaviour as one haskell program, but it would be tedious. Which is why people use haskell instead :wink:

as for actual code:

list_of_ones = repeat 1
list_of_ones = 1:list_of_ones
list_of_ones = f where f = 1 : f
all_ints = [1]++[2]++[3..]

Posted: Tue Mar 20, 2007 10:25 am
by ehird
1:2:[3..] is more haskell-y