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