digitalmars.D.learn - Infinite range of nullable elements
- Roland Hadinger (38/38) Jul 17 2015 At this moment I'm tempted to implement a function taking a range
- =?UTF-8?B?Ik3DoXJjaW8=?= Martins" (4/8) Jul 17 2015 Wouldn't it still require the algorithms to check if an element
- Roland Hadinger (9/17) Jul 17 2015 Naturally. But this check can be done further down the function
- anonymous (17/45) Jul 17 2015 The building blocks are there. You're `map`ping the original
- Roland Hadinger (2/18) Jul 17 2015 Nice! I didn't think of using 'chain'.
At this moment I'm tempted to implement a function taking a range
of elements E and returning an infinite range of Nullable!E.
With this function ("cushion" for a lack of better name) I could
do:
auto a = [0,1,2,3,4,5,6,7,8,9];
foreach (e ; a.cushion.take(20))
writeln(e); // exactly 20 elements
This would allow chaining together algorithms that need to look
ahead in a range.
Here's how I would implement the basic behaviour (could be
extended to also forward bidirectional and random access
functions):
---
auto cushion(R)(R r)
if (isInputRange!R)
{
static if (isInfinite!R) { return r; } else {
struct _Cushion(R)
{
R r;
alias E = ElementType!R;
alias NE = Nullable!E;
property bool empty() { return false; }
property NE front()
{
return !r.empty ? NE(r.front) : NE();
}
void popFront()
{
if (!r.empty) r.popFront();
}
}
return _Cushion!R(r);
}
}
---
I didn't find anything like this Phobos. Did I miss something? Is
this a bad idea for some reason?
Jul 17 2015
On Friday, 17 July 2015 at 07:42:09 UTC, Roland Hadinger wrote:At this moment I'm tempted to implement a function taking a range of elements E and returning an infinite range of Nullable!E. [...]Wouldn't it still require the algorithms to check if an element isNull()? Calling get() on a null element will assert(). I'm wondering why it asserts instead of throwing.
Jul 17 2015
On Friday, 17 July 2015 at 10:19:22 UTC, Márcio Martins wrote:On Friday, 17 July 2015 at 07:42:09 UTC, Roland Hadinger wrote:Naturally. But this check can be done further down the function chain, so all the functions before will see an infinite range. I'm currently writing a lexer (big loop with two levels of switch statements inside) that needs to some looking ahead in multiple states. Normally, each of those lookaheads would require a check for "end of input". I want to avoid this because of the large number of states.At this moment I'm tempted to implement a function taking a range of elements E and returning an infinite range of Nullable!E. [...]Wouldn't it still require the algorithms to check if an element isNull()?
Jul 17 2015
On Friday, 17 July 2015 at 07:42:09 UTC, Roland Hadinger wrote:
Here's how I would implement the basic behaviour (could be
extended to also forward bidirectional and random access
functions):
---
auto cushion(R)(R r)
if (isInputRange!R)
{
static if (isInfinite!R) { return r; } else {
struct _Cushion(R)
{
R r;
alias E = ElementType!R;
alias NE = Nullable!E;
property bool empty() { return false; }
property NE front()
{
return !r.empty ? NE(r.front) : NE();
}
void popFront()
{
if (!r.empty) r.popFront();
}
}
return _Cushion!R(r);
}
}
---
I didn't find anything like this Phobos. Did I miss something?
The building blocks are there. You're `map`ping the original
range to `Nullable`, and then you're `chain`ing an infinite range
(`cycle`) of nulls behind.
----
import std.range: isInputRange;
auto cushion(R)(R r)
if (isInputRange!R)
{
import std.algorithm: map;
import std.range: chain, cycle, ElementType, only;
import std.typecons: Nullable;
alias E = ElementType!R;
alias NE = Nullable!E;
return chain(r.map!NE, NE().only.cycle);
}
----
Jul 17 2015
On Friday, 17 July 2015 at 12:44:57 UTC, anonymous wrote:
The building blocks are there. You're `map`ping the original
range to `Nullable`, and then you're `chain`ing an infinite
range (`cycle`) of nulls behind.
----
import std.range: isInputRange;
auto cushion(R)(R r)
if (isInputRange!R)
{
import std.algorithm: map;
import std.range: chain, cycle, ElementType, only;
import std.typecons: Nullable;
alias E = ElementType!R;
alias NE = Nullable!E;
return chain(r.map!NE, NE().only.cycle);
}
----
Nice! I didn't think of using 'chain'.
Jul 17 2015









"Roland Hadinger" <rolandh.dlangforum maildrop.cc> 