On Tuesday, October 27, 2015 20:58:56 sigod via Digitalmars-d-learn wrote: > Here's simple code: > > import std.algorithm; > import std.array; > import std.file; > > void main(string[] args) > { > auto t = args[1].readText() > .splitter('\n') > .filter!(e => e.length) > .split("---") > ; > } > > Looks like it should work, but it won't compile. DMD 2.068.2 > fails with this error: > > Error: template std.algorithm.iteration.splitter cannot deduce > function from argument types !()(FilterResult!(__lambda2, > Result), string), candidates are: > ... > Error: template instance > std.array.split!(FilterResult!(__lambda2, Result), string) error > instantiating > > It compiles if I insert `.array` before `.split(...`. > > Am I missing something? Or it's a bug? I've tried to make a brief > search in the bug tracker, but didn't found anything. > > P.S. dpaste gives very strange error: > > /d712/f815.d(8): Error: unterminated character constant > /d712/f815.d(9): Error: unterminated character constant > ... and so on
Well, split calls splitter, and it doesn't make much of an attempt to check its arguments in its template constraint, mostly passing the buck onto splitter, since it's really just a wrapper around splitter that calls array on the result. You could actually reduce your code down to something more like auto t = "hello".filter!"true"().splitter(" "); and you'd have the same problem. And looking at splitter's template constraint, it requires either a narrow string (which the result of filter is not) or a range for which hasSlicing is true (which is not the case for the result of filter). Whether splitter could be implemented without that (e.g. returning a range of Take), I don't know, but it's pretty clear that the current implementation requires slicing, and if you're using filter, that means that you'd need to do something like use array to convert it to a range which _can_ be sliced to pass to split or splitter. - Jonathan M Davis