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