Reputation: 47904
According to the spec, a use
binding requires an identifier (unlike let
) instead of a pattern. Why is this? Here's an example of a scenario that doesn't work.
type Disposable = Resource of IDisposable
let f disposable =
use (Resource d) = disposable //ERROR: 'use' bindings must be of the form 'use <var> = <expr>'
()
Upvotes: 1
Views: 215
Reputation: 55185
I think the likely answer is that lots of patterns don't make sense. For instance, how would you expect the compiler to handle the following code?
type DisposablePair = DisposablePair of IDisposable * IDisposable
let f disposablePair =
use (DisposablePair(x,y)) = disposablePair
()
Your weird error message is probably due to the fact that even if you were using a let
binding, you'd need to bind (Resource d)
rather than Resource(d)
(the compiler thinks you're declaring a new function).
For what it's worth, I do find the inability to use an underscore pattern to be an annoyance at times (particularly when dealing with IDisposable
instances that exist only to demarcate scopes, like System.Transactions.TransactionScope
). One way to generalize use
bindings to handle underscores and a few other situations would be to require the right hand side of a use
binding to be an IDisposable
but to allow any pattern on the left hand side, so that:
use p = v in e
would syntactically translate to something like
let ((p:System.IDisposable) as d) = v in try e finally d.Dispose()
Upvotes: 1