Hi,
this is an interesting issue - the problem is caused by the fact that you're using "let" in the code. This in general has a structure like "let <var> = <expr>". The other option you may have considered is using "let!", which has a following structure "let! <var> = <m_expr>". The difference is that <expr> is just an ordinary code and <m_expr> is "monadic" code, which - in this case - means asynchronous code.

If you want to use asynchronous code in the exprssion that you're assigning to the variable, then you have to use the second option (let!), but unfortunately - just changing "let" to "let!" doesn't solve the problem. This is because it then expects an expression of type Async<'a> (and the code just returns a Set<string>). This can be fixed by wrapping the condition into another "async" block, like this:

(However I think it would maybe make sense to allow using "let!" in a way below without wrapping the code in additional "async" block, though the rules for this are quite difficult and I'm not sure how the compiler could deduce what behavior do you want... Anyway, the F# team is reading the forums, so they'll see your post :-) )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
// Problematic function
let urlCollector2 =
    MailboxProcessor.Start(fun self ->
        let rec waitForUrl (visited : Set<string>) =
           async { // Check the limit
                   if visited.Count < limit then
                       let! url = self.Receive()
                       let  visitedFlag = visited.Contains(url)
                       let! visited' =
                           async { if not visitedFlag then
                                       do! Async.SpawnChild
                                               (async { let! links = collectLinks url
                                                        for link in links do
                                                        do self <-- link })
                                       return visited.Add(url) 
                                   else 
                                       return visited }
                       return! waitForUrl(visited') 
                   else return () 
                  }
        waitForUrl(Set.empty))
By on 2/22/2008 12:06 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