Inheriting from sequences in Nim
Asked Answered
C

1

6

I've been experimenting with Nim for about a day now and I was wondering how you could make a type inherit from a builtin (seq specifically) so that procedures that operate on seq can also handle the custom type.

I've included a minimal example below in which a TestCol wraps/proxies a sequence - would there be a way to have TestCol support map, filter, etc without redefining the procedures?

type
  TestCol*[T] = object
    data*: seq[T]

proc len*(b: TestCol): int = b.data.len

proc `[]`*[T](b: TestCol[T], idx: int): T =
  b.data[idx]

proc `[]=`*[T](b: var TestCol[T], idx: int, item: T) =
  b.data[idx] = item

var x = newSeq[int](3)
var y = TestCol[int](data: x)

y[0] = 1
y[1] = 2
y[2] = 3

for n in map(y, proc (x: int): int = x + 1):
  echo($n)

Preferably the solution won't require transforming the custom sequence to an regular sequence for performance reasons with transforms less trivial than above (though that's what I'll do for now as def- suggested)

Real world use case is to implement array helpers on RingBuffer.nim

Charlean answered 4/5, 2015 at 16:54 Comment(0)
C
4

Implicit converters would be a way to solve this:

converter toSeq*[T](x: TestCol[T]): seq[T] =
  x.data

Unfortunately they don't get invoked when calling a proc that expects an openarray. I reported a bug about this, but I'm not sure if it can be changed/fixed: https://github.com/nim-lang/Nim/issues/2652

Cusack answered 4/5, 2015 at 17:38 Comment(1)
Is there any way for the converter to be a iterator/generator -- for example if you wanted to implement a binarySearch and the sequence was a less straightforward proxy (circular buffer in my case)Charlean

© 2022 - 2024 — McMap. All rights reserved.