On Thursday, 21 April 2022 at 21:02:47 UTC, JG wrote:
Hi,

Could someone possibly help me to understand why the commented line doesn't compile?


```d
import std;

struct MapResult(R,F)
{
    R r;
    const F f;
    auto empty() { return r.empty; }
    auto front() { return f(r.front); }
    void popFront() { r.popFront; }
    auto save() { return typeof(this)(r.save,f); }
}

auto myMap(alias f, R)(R r) {
    return MapResult!(R,typeof(f))(r,f);
}


void main()
{
   int function(int) f = x=>2*x;
   iota(10).myMap!f.writeln;
//iota(10).myMap!(x=>2*x).writeln; <--- Why doesn't this compile?

}
```

(I do know that Phobos's map works differently with better performance).


Thank you to all for the great replies. To fix it one could do:

```d
import std;

    struct MapResult(R,F) {
        R r;
        const F f;
        auto empty() { return r.empty; }
        auto front() { return f(r.front); }
        void popFront() { r.popFront; }
        auto save() { return typeof(this)(r.save,f); }
    }

    auto myMap(alias f, R)(R r) {
        static if(__traits(compiles,f!(typeof(R.init.front)))) {
            auto fun = f!(typeof(R.init.front));
            return MapResult!(R,typeof(fun))(r,fun);
        } else {
        return MapResult!(R,typeof(f))(r,f);
        }
    }


    void main()
    {
       int function(int) f = x=>2*x;
       iota(10).myMap!f.writeln;
       iota(10).myMap!(x=>2*x).writeln;

    }
    ```

In response to the change to "alias", which has several upsides
including faster code. I would note it also has some downsides including every lambda produces a new type so that (at the moment) the following assert
holds:
```d
auto r = iota(10).map!(x=>x+1);
auto s = iota(10).map!(x=>x+1);
assert(!is(typeof(r)==typeof(s)));
```

Reply via email to