www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to use map?

reply "Lemonfiend" <lemon fie.nd> writes:
I'm trying to do something simple like creating an array of 
struct S from a float array via map:

---
void main()
{
	float[] vals = [1.1, 2.1, 3.1, 4.1];

	import std.algorithm: map;
	auto arr = vals.map!`S(a)`.array;
	writeln(arr);
}

struct S(T)
{
	T t;
}
---

But I get:
---
C:\D\dmd2\windows\bin\..\..\src\phobos\std\functional.d-mixin-49(49): 
Error: undefined identifier S
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(480): 
Error: template instance std.functional.unaryFun!("S(a)", 
"a").unaryFun!float error instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(427):      
   instantiated from here: MapResult!(unaryFun, float[])
src\app.d(28):        instantiated from here: map!(float[])
---

If I instead do ie. map!`cast(int)a` it works fine.
What am I missing?
Nov 11 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Lemonfiend:

 If I instead do ie. map!`cast(int)a` it works fine.
 What am I missing?
Generally don't use casts, unless you know what you are doing (and often you don't). The code you were trying to write: struct Foo(T) { T t; } void main() { import std.stdio, std.algorithm, std.array; float[] vals = [1.1, 2.1, 3.1, 4.1]; auto arr = vals.map!(Foo!float).array; arr.writeln; } Bye, bearophile
Nov 11 2014
parent reply "Lemonfiend" <lemon fie.nd> writes:
 The code you were trying to write:

 struct Foo(T) {
     T t;
 }

 void main() {
     import std.stdio, std.algorithm, std.array;

     float[] vals = [1.1, 2.1, 3.1, 4.1];
     auto arr = vals.map!(Foo!float).array;
     arr.writeln;
 }
Sorry, my example had an unneeded template. Simply this (and also your code) --- struct S { float f; } --- still results in an undefined identifier.
Nov 11 2014
parent reply "Lemonfiend" <lemon fie.nd> writes:
Oh, no it doesn't. My bad.

It was all about !(Foo) vs !(`Foo(a)`). Is there somewhere I can 
read more about this?
Nov 11 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 11 November 2014 at 14:09:43 UTC, Lemonfiend wrote:
 Oh, no it doesn't. My bad.

 It was all about !(Foo) vs !(`Foo(a)`). Is there somewhere I 
 can read more about this?
Don't know whether it's documented, but it's a consequence of using string mixins. unaryFun (which is used internally by map) is implemented this way: auto unaryFun(ElementType)(auto ref ElementType __a) { mixin("alias " ~ parmName ~ " = __a ;"); return mixin(fun); } where `fun` is `Foo(a)`. Of course, `Foo` is not visible in std.functional. When you pass in a symbol, the lookup work because it takes place at the point of instantiation.
Nov 11 2014
parent "Lemonfiend" <lemon fie.nd> writes:
On Tuesday, 11 November 2014 at 15:53:37 UTC, Marc Schütz wrote:
 Don't know whether it's documented, but it's a consequence of 
 using string mixins.

 unaryFun (which is used internally by map) is implemented this 
 way:

     auto unaryFun(ElementType)(auto ref ElementType __a)
     {
         mixin("alias " ~ parmName ~ " = __a ;");
         return mixin(fun);
     }

 where `fun` is `Foo(a)`. Of course, `Foo` is not visible in 
 std.functional. When you pass in a symbol, the lookup work 
 because it takes place at the point of instantiation.
That makes sense, thanks.
Nov 11 2014