Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
December 10, 2013 Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Hello, here is example code, which doesn't work: Variant[] vtypes = [ Variant("hello"), Variant("bye") ]; string[] filetypes = map!(to!string)(vtypes); Gives me error: Error: cannot implicitly convert expression (map(vtypes)) of type MapResult!(to, VariantN!(24u)[]) to string[] .... And alternative version: Variant[] vtypes = [ Variant("hello"), Variant("bye") ]; string[] ftypes = map!(t => t.get!(string))(vtypes); Error: cannot implicitly convert expression (map(vtypes)) of type MapResult!(__lambda2, VariantN!(24u)[]) to string[] .... What is wrong here and how to fix it ? |
December 10, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | On Tue, Dec 10, 2013 at 6:54 AM, Dfr <deflexor@yandex.ru> wrote: > Hello, here is example code, which doesn't work: > > Variant[] vtypes = [ Variant("hello"), Variant("bye") ]; > string[] filetypes = map!(to!string)(vtypes); > > Gives me error: > > Error: cannot implicitly convert expression (map(vtypes)) of type > MapResult!(to, VariantN!(24u)[]) to string[] > What is wrong here and how to fix it ? map, and with it most other algorithm and ranges in std.algorithm and std.range, returns lazy ranges: structs that will produce the data you want when you iterate on them (with foreach, for example). What map!(to!string)(someArray) does is constructing a 'view' on someArray that will get you someArray elements, concerted into string. If you want to convert it into an array, use std.array.array: import std.stdio; import std.algorithm; import std.range; import std.array; import std.conv; import std.variant; void main() { Variant[] vtypes = [ Variant("hello"), Variant("bye"), Variant(3.1415) ]; string[] filetypes = map!(to!string)(vtypes).array(); writeln(filetypes); } |
December 10, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Thank you for good explanation. But i currently hit little more complex case and again stuck, maybe some ideas how to resolve this, unfortunately compiler messages not very explanatory. void main() { Variant[] lols = [ Variant(["hello": Variant(1)]), Variant(["bye": Variant(true)]) ]; auto vtypes = map!(to!Variant[string])(lols); // <--- line 11 string[] filetypes = map!(to!string)(vtypes).array(); writeln(filetypes); } Gives me: main.d(11) Error: to!(VariantN!(24u)) is used as a type On Tuesday, 10 December 2013 at 06:05:50 UTC, Philippe Sigaud wrote: > On Tue, Dec 10, 2013 at 6:54 AM, Dfr <deflexor@yandex.ru> wrote: >> Hello, here is example code, which doesn't work: >> >> Variant[] vtypes = [ Variant("hello"), Variant("bye") ]; >> string[] filetypes = map!(to!string)(vtypes); >> >> Gives me error: >> >> Error: cannot implicitly convert expression (map(vtypes)) of type >> MapResult!(to, VariantN!(24u)[]) to string[] > >> What is wrong here and how to fix it ? > > map, and with it most other algorithm and ranges in std.algorithm and > std.range, returns lazy ranges: structs that will produce the data you > want when you iterate on them (with foreach, for example). > > What map!(to!string)(someArray) does is constructing a 'view' on > someArray that will get you someArray elements, concerted into string. > > If you want to convert it into an array, use std.array.array: > > import std.stdio; > import std.algorithm; > import std.range; > import std.array; > import std.conv; > import std.variant; > > void main() > { > Variant[] vtypes = [ Variant("hello"), Variant("bye"), Variant(3.1415) ]; > string[] filetypes = map!(to!string)(vtypes).array(); > writeln(filetypes); > } |
December 10, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | Dfr: > auto vtypes = map!(to!Variant[string])(lols); The short template instantiation syntax only supports a single token, to avoid mistakes,so you need to add (): map!(to!(Variant[string]))(lols); That is better written: lols.map!(to!(Variant[string])); But I don't know if this is enough to fix your code. Bye, bearophile |
December 10, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | > void main()
> {
> Variant[] lols = [ Variant(["hello": Variant(1)]), Variant(["bye":
> Variant(true)]) ];
> auto vtypes = map!(to!Variant[string])(lols); // <--- line 11
>
> string[] filetypes = map!(to!string)(vtypes).array();
> writeln(filetypes);
> }
>
> Gives me:
> main.d(11) Error: to!(VariantN!(24u)) is used as a type
As bearophile said, to!Variant[string]... is read as to!(Variant)[string], which is not what you want. When a template argument is more than one token long (Variant[string] has 4 tokens), enclose it in parenthesis.
But here it will not help you, as I think the conversion you ask is impossible: how could a Variant be transformed into a Variant[string]? By definition of Variant, the compiler cannot know what is inside. The first element of lol could be an a float wrapped into a Variant, for example, and then how could it be transformed into Variant[string]?
Do you really need to enclose everything in Variants? Types are your friends, you know :)
An array of Variant[string] would be far easier to work with:
import std.stdio;
import std.algorithm;
import std.range;
import std.array;
import std.conv;
import std.variant;
void main()
{
// See the type of lols
Variant[string][] lols = [ ["hello": Variant(1)], ["bye": Variant(true)] ];
string[] filetypes = map!(to!string)(lols).array();
writeln(filetypes);
}
|
December 11, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud |
Thank you, this clears thing to me.
I currently has all stuff wrapped in Variants because it is structure parsed from xml (or json), and it could be for example map of Something[string], where Something could be string or array or another map, and also this all nested few levels deep. I'm new to D and maybe there is better solution exists how to represent such structure ?
On Tuesday, 10 December 2013 at 18:40:48 UTC, Philippe Sigaud wrote:
>> void main()
>> {
>> Variant[] lols = [ Variant(["hello": Variant(1)]), Variant(["bye":
>> Variant(true)]) ];
>> auto vtypes = map!(to!Variant[string])(lols); // <--- line 11
>>
>> string[] filetypes = map!(to!string)(vtypes).array();
>> writeln(filetypes);
>> }
>>
>> Gives me:
>> main.d(11) Error: to!(VariantN!(24u)) is used as a type
>
> As bearophile said, to!Variant[string]... is read as
> to!(Variant)[string], which is not what you want. When a template
> argument is more than one token long (Variant[string] has 4 tokens),
> enclose it in parenthesis.
>
> But here it will not help you, as I think the conversion you ask is
> impossible: how could a Variant be transformed into a Variant[string]?
> By definition of Variant, the compiler cannot know what is inside. The
> first element of lol could be an a float wrapped into a Variant, for
> example, and then how could it be transformed into Variant[string]?
>
> Do you really need to enclose everything in Variants? Types are your
> friends, you know :)
>
> An array of Variant[string] would be far easier to work with:
>
> import std.stdio;
> import std.algorithm;
> import std.range;
> import std.array;
> import std.conv;
> import std.variant;
>
> void main()
> {
> // See the type of lols
> Variant[string][] lols = [ ["hello": Variant(1)], ["bye": Variant(true)] ];
>
> string[] filetypes = map!(to!string)(lols).array();
> writeln(filetypes);
> }
|
December 11, 2013 Re: Using std.algorithm.map: Error: cannot implicitly convert expression of type MapResult! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dfr | On Wed, Dec 11, 2013 at 7:26 AM, Dfr <deflexor@yandex.ru> wrote:
>
> Thank you, this clears thing to me.
>
> I currently has all stuff wrapped in Variants because it is structure parsed from xml (or json), and it could be for example map of Something[string], where Something could be string or array or another map, and also this all nested few levels deep. I'm new to D and maybe there is better solution exists how to represent such structure ?
For JSON, since the range of types is quite limited, different solutions exists, that depend on what kind of code you prefer:
- Having a JSONNode type (a struct, or a class) with a 'type' field
(say, a string), that would store whether it's a JSON string, an array
of other JSON elements, or a map of JSON elements.
Since the range of JSON types is limited, you could have an external
enum (enum JSONType {String, Array, Map, ... }) and have you JSONNode
contain a member of this kind.
External code could then check this field to act accordingly.
- Having a hierarchy of class, with a root JSONNode (abstract, I
suppose) class, and other, derived classes (JSONArray, JSONMap, ...).
A JSONArray would contain an array of JSONNode's, and so on.
- Having a bunch of templated structs that would hold together by template constraints, but I don't have the space here to explain it. It's much more complicated and the only advantage I see is being able to construct a value at compile-time.
- Using std.variant.Algebraic instead of std.variant.Variant is also an option.
For XML, that depends whether you have a DTD, a Schema or whatever, something that limits the kind of XML files you'll receive.
- If not, then use a simple node struct, with a name (the XML node
name) and an array of nodes as children. It'll give you a generic
tree, that is quite OK to represent XML. classes or structs are OK and
are mainly a matter of taste here (other might chime in this thread
and have other arguments, I'm more a struct guy myself).
You'd have to think about how to correclty represent attributes.
That also depend of your end goal: just learning to read and manipulate this kind of data in D? Or create a new XML value and write it somewhere? Validation of content (when reading) or allowing the construction only of valid values (when creating) are also interesting subjects.
- If you have a DTD and it's fixed, then you can follow the JSON approach: a hierarchy of XML nodes, each containing what's required by the DTD.
- If you know you have a DTD but do not know it in advance, then it's still possible, but not in a forum post :) You would have to first parse the DTD, determine what kind of XML node is authorized and then create the required D code. Just know it's perfectly feasible, though more advanced than the other solutions.
Cheers,
Philippe
|
Copyright © 1999-2021 by the D Language Foundation