This is a type to represent lazy ranges parametrized by the container type:
type Range[V] = object
v: V
slice: Slice[int]
var r: Range[seq[int]] = Range[seq[int]](v: @[0, 10, 20, 30, 40], slice: 2..3)
# r represents the range [20, 30]
var x : r.v[0].type # ok: r.v[0].type is int, the type of the elements, so x is an int
#If I want a generic proc to get the first element of a Range:
proc first[V](r: Range[V]): r.v[0].type = #ohhh, here r.v[0].type doesn't work: "undeclared field v"
return r.v[r.slice.a]
echo first(r) # Would be 20
Any idea to declare the "first" proc?Regarding lazy ranges, @timotheecour was interested in implementing D ranges in Nim, see https://github.com/timotheecour/vitanim/tree/master/drange/src/drange.
I often struggled with the same need, Nim offers genericHead but no subtype retrieval from a container by default.
See my feature request #6454.
At the moment I would use auto, you can't do as much in type signatures (even if you use a macro the V would likely not be expanded).
type Range[V] = object
v: V
slice: Slice[int]
var r: Range[seq[int]] = Range[seq[int]](v: @[0, 10, 20, 30, 40], slice: 2..3)
# r represents the range [20, 30]
var x : r.v[0].type # ok: r.v[0].type is int, the type of the elements, so x is an int
#If I want a generic proc to get the first element of a Range:
proc first[V](r: Range[V]): auto = #ohhh, here r.v[0].type doesn't work: "undeclared field v"
return r.v[r.slice.a]
echo first(r) # Would be 20
Any problem on Earth can be solved with the careful application of meta-programming. The trick is not to be around when the AST spec changes. :o)
import macros
type Range[V] = object
v: V
slice: Slice[int]
var r: Range[seq[int]] = Range[seq[int]](v: @[0, 10, 20, 30, 40], slice: 2..3)
# r represents the range [20, 30]
var x : r.v[0].type # ok: r.v[0].type is int, the type of the elements, so x is an int
macro elemType(t: typed): untyped =
t.getTypeImpl[1][1].copy
#If I want a generic proc to get the first element of a Range:
proc first[V](r: Range[V]): V.elemType =
return r.v[r.slice.a]
echo first(r) # Would be 20