Hide this comment

You can't use a try/with in a sequence expression as a control flow operator, but you can use them in sub-expressions. What I mean is that this won't work:

1
2
3
4
5
6
seq {
  try
    yield 1/0
  with
    _ -> yield -1
}

but this equivalent code will:

1
2
3
4
5
6
seq {
  yield 
    (try 
       1/0 
     with _ -> -1)
}

Depending on what type of exception handling you are trying to do, this may be enough. Be careful, though, since the delayed execution inherent to sequence expressions can be a bit confusing. For example, this might not do what you expect:

1
2
3
4
5
6
seq {
  yield! 
    (try 
       seq { yield 1/0 } 
     with _ -> Seq.empty)
}

If this approach isn't enough for your use cases, one alternative option would be to build your own sequence builder which does allow try/with. Try this:

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
type SequenceBuilder() =
  member x.Delay f = Seq.delay f
  member x.Combine(r,s) = Seq.append r s
  member x.For(s,f) = Seq.collect f s
  member x.Yield(v) = Seq.singleton v
  member x.YieldFrom(s) = s
  member x.Zero() = Seq.empty
  member x.While(f,s) = seq { while f() do yield! s }
  member x.Using(d,f) = seq { use x = d in yield! f x }
  member x.TryFinally(s,f) = seq { try yield! s finally f() }
  member x.TryWith(s:_ seq,f) =
    Seq.delay (fun () ->
      try
        let e = s.GetEnumerator()
        let rec loop() =
          try
            if (e.MoveNext()) then
              let v = e.Current
              seq { yield v; yield! loop() }
            else Seq.empty
          with ex -> f ex
        loop()
      with ex -> f ex)


let seq' = SequenceBuilder()


let example = seq' {
  let x = ref 6
  try
    while true do
      yield 300 / !x
      x := !x - 1
  with ex -> yield -1 }

There will be a bit of a performance hit to using seq' instead of seq because the compiler converts normal sequence expressions into optimized state machines, but being able to write your code in a more natural way may be worth it.

By on 3/30/2010 4:13 PM ()Reply
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

Logging in...