[challenge] Lazy flatten/avoiding type forward reference with map
Ali Çehreli
acehreli at yahoo.com
Thu Oct 31 14:19:48 PDT 2013
On 10/31/2013 12:09 PM, David Nadlinger wrote:
> A while back, somebody raised the topic of implementing a lazy range for
> traversing/flattening a tree structure on #d.
>
> The obvious (in terms of Phobos primitives) solution would be something
> along the lines of this:
> ---
> struct Node(T) {
> T val;
> Node!T[] children;
> }
>
> auto flatten(T)(Node!T root) {
> import std.algorithm, std.range;
> return only(root.val).chain(map!flatten(root.children).joiner);
> }
>
> void main() {
> alias N = Node!int;
> auto a = N(1, [
> N(2, [
> N(3, [
> N(4)
> ])
> ]),
> N(5)
> ]);
>
> import std.stdio;
> writeln(a.flatten); // [1, 2, 3, 4, 5]
> }
> ---
>
> But of course, that piece of code does not compile with current DMD, as
> the return type of flatten() can't refer to the function itself (during
> name mangling).
>
> Now, one way around this would be to add an array() call at the end of
> the return statement, which hides the type of map!flatten, but at the
> cost of many unnecessary memory allocations. A second option would be to
> use inputRangeObject to convert the return value to ForwardRange!T
> (well, that is if it actually worked, due to an implementation bug it
> leads to a runtime crash).
>
> But can you think of a more simple/elegant workaround?
>
> (Note aside: Obviously, the fact that the code relies on recursion might
> be an issue, and a simple opApply-based solution with a worklist stack
> would likely perform better. Still, I think it's a simple, yet
> interesting problem.)
>
> David
Y Combinator? (No, I have not solved it yet. :) )
http://rosettacode.org/wiki/Y_combinator#D
Ali
More information about the Digitalmars-d-learn
mailing list