[Issue 15972] New: joiner doesn't recognize range of chars
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Fri Apr 29 12:02:52 PDT 2016
https://issues.dlang.org/show_bug.cgi?id=15972
Issue ID: 15972
Summary: joiner doesn't recognize range of chars
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P1
Component: phobos
Assignee: nobody at puremagic.com
Reporter: hsteoh at quickfur.ath.cx
Code:
-------
auto triangle(int i) {
import std.algorithm.iteration : map, joiner;
import std.range : iota, repeat;
return iota(i).map!(i => '#'.repeat(i))
.joiner("\n");
}
void main() {
import std.stdio : writeln;
writeln(triangle(10));
}
-------
Compile error:
-------
test.d(5): Error: template std.algorithm.iteration.joiner cannot deduce
function from argument types !()(MapResult!(__lambda2, Result), string),
candidates are:
/usr/src/d/phobos/std/algorithm/iteration.d(1949):
std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator sep) if
(isInputRange!RoR && isInputRange!(ElementType!RoR) && isForwardRange!Separator
&& is(ElementType!Separator : ElementType!(ElementType!RoR)))
/usr/src/d/phobos/std/algorithm/iteration.d(2232):
std.algorithm.iteration.joiner(RoR)(RoR r) if (isInputRange!RoR &&
isInputRange!(ElementType!RoR))
-------
A little sleuthing with pragma(msg) reveals that the problem is caused by
'#'.repeat(i) returning a range of char (as opposed to a range of dchar, which
is what usually happens when strings are used with joiner), but strings (as
well as char literals such as writing '\n' instead of "\n") are always ranges
of dchar (no thanks to autodecoding), so joiner's signature constraints will
fail because it tries to check implicit conversion of the delimiter element
type (in this case always dchar) to the target range type (char), and is(dchar
: char) is false.
Workaround:
--------
auto triangle(int i) {
import std.algorithm.iteration : map, joiner;
import std.range : iota, repeat;
import std.utf : byCodeUnit; // this is a hack
return iota(i).map!(i => '#'.repeat(i))
.joiner("\n".byCodeUnit);
}
void main() {
import std.stdio : writeln;
writeln(triangle(10));
}
--------
This is very silly, since nobody not already familiar with the intricacies of
autodecoding will even have the slightest idea what the problem is and how to
work around it. My personal recommendation: kill autodecoding with fire.
--
More information about the Digitalmars-d-bugs
mailing list