Thread overview
Trying to search a range
Jul 03, 2021
Kevin Bailey
Jul 03, 2021
Paul Backus
Jul 03, 2021
Kevin Bailey
July 03, 2021

Sorry if this is too simple of a question, but I'm trying to simply find
a blank line in a file. I'm doing something like:

auto file = File("somefile");
auto r = file.byLine();
auto tup = r.findSplit("");
// tup[0] would contain the range before the line,
// tup[2] would contain the range after, not unlike findSplit

Unfortunately, ldc2 is saying:

split.d(8): Error: template std.algorithm.searching.findSplit cannot deduce function from argument types !()(ByLineImpl!(char, char), string), candidates are:
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/algorithm/searching.d(2882):        findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
  with pred = "a == b",
       R1 = ByLineImpl!(char, char),
       R2 = string
  must satisfy the following constraint:
       isForwardRange!R1

I can't tell if findSplit() only works on strings, or if maybe I'm
trying to compare different types of strings, or if I'm overtaxing
the type deduction system.

July 03, 2021

On Saturday, 3 July 2021 at 00:29:23 UTC, Kevin Bailey wrote:

>

Unfortunately, ldc2 is saying:

split.d(8): Error: template std.algorithm.searching.findSplit cannot deduce function from argument types !()(ByLineImpl!(char, char), string), candidates are:
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/algorithm/searching.d(2882):        findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
  with pred = "a == b",
       R1 = ByLineImpl!(char, char),
       R2 = string
  must satisfy the following constraint:
       isForwardRange!R1

The error message here is actually telling you exactly what the problem is: findSplit requires a forward range, but the range returned by File.byLine is not a forward range, just an input range.

import std.range;
pragma(msg, isForwardRange!(typeof(File("somefile").byLine())));
// prints "false"

The difference between an forward range and an input range is that forward ranges implement .save, a method that allows you to save your place in the range and return to it later. The range returned by File.byLine doesn't have this method because it's not always possible to save your place in a file (for example, if you're reading from a pipe).

To work around this, you can either (a) read the whole file into memory before using findSplit on it, or (b) redesign your algorithm to work in a single pass over the input file.

July 03, 2021

On Saturday, 3 July 2021 at 01:15:20 UTC, Paul Backus wrote:

>

The error message here is actually telling you exactly what the problem is: findSplit requires a forward range, but the range returned by File.byLine is not a forward range, just an input range.

Hey Paul,

Thanks for the pointer. I doubt I would have figured out that
surprising detail. Nevertheless, now I know where to look for
the exact error. :-)