I think I can take a stab at this, although I'm sure someone else might have more to add.

Now my first question is why doesn't it return back

seq<int> = seq {1; 2; 3;}

I think this is just a matter of how the pretty printer displays it. Semantically, you have a sequence which contains the values 1, 2, and 3. The representation "seq [1; 2; 3]" is simply a way of displaying that to you in a friendly readable format. It doesn't imply anything about the structure of the underlying sequence.

My next question is why doesn't it say
list <int> = seq [1; 2; 3]

Because it's not a list. It's true that [1; 2; 3] is a list. But seq {1 .. 3} is not a List<int>, it's a Seq<int>, which is a very specific type. List<int> is *compatible* with Seq<int>, but all that means is that you can convert between the two. The biggest difference between seq and list is that seq is *lazy*. Meaning that you can have an infinite seq, but you cannot have an infinite list, because the n'th element of a seq is only computed when it is actually accessed. Of course it's easy to initialize a seq with a list, because a Seq<> is a *potentially* infinite list. So you can definitely initialize this with a finite list.

By lazy, what I mean is that when you specify let x = seq { 1 .. 100 }, you are not actually generating a list of the first 100 positive integers. Rather, you are generating an *enumerator* of the first 100 integers. Not a single one of those integers has actually been determined yet. Instead, under the hood, there is a function that knows how to calculate the k'th integer, and when you ask for the k'th value, it actually runs that function on the fly. As an example of the utility of this, you can for example store every single prime number in existence in a seq<int>. If you want the 7 millionth prime, assuming you have defined a Seq<int> called 'primes' appropriately (which will involve some code specifying the actual formula for primes, perhaps using a Sieve of Eratosthenes), you can say

Seq.nth 7000000 primes

This is not possible with a list, because every single value must be computed up front with a list before you can even deal with the object.

My last question is how can one go about creating a sequence without the .. operator?

In a code window, type the following:

Seq.

this will bring up the intellisense for seq. Notice there is a member called of_list. This is what you want.

> Seq.of_list [1; 2; 3];;
val it : seq<int> = [1; 2; 3]
> Seq.of_array [|1; 2; 3|];;
val it : seq<int> = [1; 2; 3]

By on 12/8/2008 11:19 AM ()

Thanks for the reply. You have confirmed what I was thinking. Do you know (just curious) if there is a syntax though to create a Seq without calling a class method like of_list or of_array? Or do you think this is the only way?

By on 12/8/2008 11:41 AM ()

You could also upcast a list or array to an IEnumerable / seq:

1
2
3
let s = [1;2;3] :> seq< int>

Edit: added space before int because the forum doesn't show it right.

By on 12/8/2008 12:03 PM ()

I guess you could write something obtuse like:

let l = [1; 2; 3; 4; 5];;
seq { for i in l -> i }

Just curious why you want to avoid a function call?

By on 12/8/2008 11:57 AM ()

Hi,
regarding creating of sequences without converting them from an array or a list -
You can use explicit "sequence expression" syntax to do this. A simple example would be:

1
2
 
seq { yield 1; yield 2; yield 3; };;

BTW: this feature is more universal and you can use it to write all sorts of interesting things:

1
2
3
4
5
 
> seq { for i in 1 .. 4 do
-         yield i
-         if (i%2=0) then yield 100*i };;
val it : seq<int> = seq [1; 2; 200; 3; ...]
By on 12/8/2008 11:55 AM ()
1
2
 
seq { yield 1; yield 2; yield 3; };;

This is just what I was looking for. Thanks!

Is it necessary to use yield because of the lazy nature of Seq?

By on 12/8/2008 12:25 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper