ReturnType of lambda templates
John Colvin via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Aug 18 08:11:32 PDT 2015
On Tuesday, 18 August 2015 at 14:25:34 UTC, Roland Hadinger wrote:
> Hi!
>
> Suppose I wanna do this (which already works, which is why D is
> pretty cool):
>
> import std.traits;
> import std.typecons : Nullable;
>
> // Retrofit Nullable to allow for monadic chaining
> //
> auto apply( alias fun, T )( Nullable!T nullable )
> if( isSomeFunction!fun )
> {
> enum returnsVoid = is( ReturnType!fun == void );
> enum returnsNullable = is( ReturnType!fun : Nullable!X,
> X );
>
> static if( returnsVoid ) {
>
> if( !nullable.isNull )
> fun( nullable.get );
>
> } else static if( returnsNullable ) {
>
> alias NR = ReturnType!fun;
>
> if( nullable.isNull )
> return NR();
> else
> return fun( nullable.get );
>
> } else {
>
> alias NR = Nullable!( ReturnType!fun );
>
> if( nullable.isNull )
> return NR();
> else
> return NR( fun( nullable.get ) );
> }
> }
>
> void main()
> {
> Nullable!int a = 1;
> Nullable!int b = a.apply!( (int x) => 2 * x );
> // .apply!( (double x) => foo( x, u ) )
> // .apply!( (double x) => bar( x, v ) )
> // .apply!( (string x) => baz( x, w ) );
> }
>
> ...but without explicitly specifying the type of the lambda
> parameter:
>
> void main()
> {
> Nullable!int a = 1;
> Nullable!int b = a.apply!( x => 2 * x );
> // .apply!( x => foo( x, u ) )
> // .apply!( x => bar( x, v ) )
> // .apply!( x => baz( x, w ) );
> }
>
> Problem is, the shorter form involves lambda templates, and
> both 'isSomeFunction' and 'ReturnType' currently don't seem to
> work
> with those. No problems with the other version.
>
> Can I fix my 'apply' function to still allow for the less
> verbose form?
>
> If that's impossible, is it a theoretical possibility to
> improve D's type deduction to handle this?
>
> Or should I just not attempt to write code like this for the
> time being (after all, functional code like this incurs some
> overhead, but in this particular case, I'd prefer legibility
> over performance)?
>
> Thanks!
for simple lambdas like that (i.e. function templates with one
template arguments that corresponds to the type of the first and
only argument), just add this template overload:
auto apply( alias fun, T )( Nullable!T nullable )
if( !isSomeFunction!fun )
{
return .apply!(fun!T, T)(nullable);
}
and it should work (give or a take a few typos on my part).
More information about the Digitalmars-d-learn
mailing list