Skip to content

Instantly share code, notes, and snippets.

@mausch
Created May 7, 2012 20:01
Show Gist options
  • Save mausch/2630024 to your computer and use it in GitHub Desktop.
Save mausch/2630024 to your computer and use it in GitHub Desktop.
VB.NET funcs
Just found out that VB.NET can infer function types correctly. I.e. this won't work in C#:
var withMemoryStream =
(Action<MemoryStream> f) => () => {
using (var ms = new MemoryStream())
f(ms);
};
("Cannot assign lambda expression to implicitly-typed local variable", because it can't tell a Func<T> from an Expression<Func<T>>).
But the exact same code in VB.NET does work:
Dim withMemoryStream =
Function(f As Action(Of MemoryStream)) _
Sub()
Using ms = New MemoryStream
f(ms)
End Using
End Sub
Not bad, VB.NET, not bad.
People usually type explicitly their Funcs in C#:
Func<Action<MemoryStream>, Action> withMemoryStream =
f => () => {
using (var ms = new MemoryStream())
f(ms);
};
But I never leave home without my trusty extensions to prod the C# type inferencer:
public static class L {
public static Func<A,R> F<A,R>(Func<A,R> f) {
return f;
}
// overloads for other type arity...
public static Action A(Action a) {
return a;
}
}
var withMemoryStream =
L.F((Action<MemoryStream> f) =>
L.A(() => {
using (var ms = new MemoryStream())
f(ms);
}));
And of course this is a no-brainer with F#, which is why higher-order functions are so much more natural:
let withMemoryStream f () =
use ms = new MemoryStream()
f ms
Though to be more precise, this uses F# function types, not Func and Action. If you wanted to achieve the *exact* same signature it needs some wrappers and gets ugly:
let withMemoryStream =
let w f () =
use ms = new MemoryStream()
f ms
Func<Action<_>,_>(fun f -> Action(w f.Invoke))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment