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