How To: Passing curried functions around

Bahman Movaqar via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 11 02:41:41 PDT 2015


On Friday, 11 September 2015 at 06:14:18 UTC, Ali Çehreli wrote:
> On 09/06/2015 12:05 PM, Bahman Movaqar wrote:
> >      alias bool function(int n) validator_t;
>
> There is the relatively newer alias syntax which is more 
> intuitive:
>
> alias Validator = bool function(int n);

Great.  This is easily read by my eyes.

> partial takes the function arguments as 'value template 
> parameters'. Unfortunately, a function pointer like &isEven 
> cannot be 'value template parameters'; only fundamental types 
> and strings can... So, 'partial' is not an option for this 
> problem.

Ah...now I understand the mysterious compiler errors.

> Idiomatic D uses templates and passes behavior in the form of 
> 'alias template parameters.' Alias template parameters are the 
> convenient way of allowing anything that is callable, not just 
> functions. For example, foo() would be much more useful if it 
> allowed a delegate or a class object that has an overloaded 
> opCall() operator.

True.  I guess I was just pushing D functions too far.

> > and even
> > if this is the correct way of currying `readInt`, what should
> be the
> > signature of `foo`?
>
> I think 'int delegate()' would do because all foo needs is a 
> function that returns an int.

That's correct.  I realised this subtle point later on, but had 
already switched to a `struct`y approach.

>
> The idiomatic way is to leave it as a template parameter. 
> However, this has the problem of making each instantiation of 
> the foo template a different type, making them incompatible to 
> be elements of the same array:
>
> [ &(foo!myReader), &(foo!yourReader) ]  // <-- compilation error
>
> One solution is to do what std.parallelism.task does: to 
> provide both a foo template and another foo function that takes 
> an 'int delegate()':
>
>   http://ddili.org/ders/d.en/parallelism.html
>
> (Search for "The task function above has been specified as a 
> template parameter" on that page.)

Actually, I *am* using your book (which is, by the way, very well 
written) plus the language specs to learn D.  However, that 
section yet too advance for me to touch :-)

> import std.stdio;
>
> bool isEven(int n) {
>     return !(n % 2);
> }
>
> int readValidInt(alias validator)(string prompt) {
>     while (true) {
>         int i;
>         write(prompt);
>         readf(" %s", &i);
>         if (validator(i)) {
>             return i;
>         } else {
>             writeln("Sorry, that's not acceptable");
>         }
>     }
> }
>
> void foo(alias reader)() {
>     reader();
> }
>
> void main() {
>     auto reader = () => readValidInt!isEven("Enter an integer: 
> ");
>
>     foo!reader();
> }
>
> You can add template constraints to make the code easier to use.

Clean one!  Even though I don't know what's going behind the 
scenes, I can easily read and understand it.

Thanks for the help.




More information about the Digitalmars-d-learn mailing list