No, in F# you can't use a value before it's defined, e.g.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 

let a = [1; 1; 2; 2; 3; 3]

// fails at runtime, 'b' uses self before definition is finished
//let rec b = [for s in a do
//                if not(List.contains s b) then
//                    yield s]

// yuck, I get StackOverflowException:
//let rec b = seq {
//            for s in a do
//                if not(Seq.exists (fun x -> x=s) b) then
//                    yield s} 

LazyList is often useful for similar kinda of cases where you produce values based on previous values, provided the algorithm doesn't try to 'read past what's been created' yet... the Python example appears to take advantage of mutation and let you 'observe' the 'end' of the list which later gets mutated as more elements are created (as far as I can tell; I don't know Python). Of course, if you want to go that route, it's easy:

1
2
3
4
5
6
7
8
9
10
 

let b = 
    let r = new System.Collections.Generic.List<int>()
    for s in a do
        if not(r.Contains(s)) then
            r.Add(s)
    r |> Seq.to_list 

but no comprehension syntax here (modulo the fact that F# comprehension syntax is almost exactly the same as normal F# code, save 'yield').

By on 7/11/2009 10:52 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