Skip to content

Instantly share code, notes, and snippets.

@rayman22201
Created January 16, 2019 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rayman22201/92f28f0c1d9ccbc5a36fe04c2132c49e to your computer and use it in GitHub Desktop.
Save rayman22201/92f28f0c1d9ccbc5a36fe04c2132c49e to your computer and use it in GitHub Desktop.
minimal tree generic error
type
BBTree*[K,V] = ref object of RootObj # BBTree is a generic type with keys and values of types K, V
## `BBTree` is an opaque immutable type.
BBLeaf[K,V] = ref object of BBTree
key: K # the search key; must support the generic ``cmp`` proc
val: V # the data value associated with the key, and stored in a node
BBNode2[K,V] = ref object of BBLeaf
left: BBTree[K,V] # left subtree; may be nil
right: BBTree[K,V] # right subtree; may be nil
size: int # the size of the (sub-)tree rooted in this node
func size[K,V](n: BBLeaf[K,V]): int = return 1
func left[K,V](n: BBLeaf[K,V]): BBTree[K,V] = return nil
func right[K,V](n: BBLeaf[K,V]): BBTree[K,V] = return nil
iterator inorder*[K,V](root: BBTree[K,V]): (K,V) =
var curr = root
while (not curr.isNil):
curr = curr.left
var root : BBTree[int,int] = nil
for k,v in inorder(root):
echo k, v
@timotheecour
Copy link

timotheecour commented Jan 17, 2019

(that was in reply to https://forum.nim-lang.org/t/4566, where above snippet gave

Error: cannot instantiate: 'BBTree'
        curr = curr.left

)

you can't implicitly upcast (in any language that I know of); use a cast or maybe there's a safer /less blunt approach than cast, idk; maybe @Araq knows (ie analog of C++ dynamic_cast) EDIT => see below for better version

but this compiles: (also changed BBLeaf[K,V] = ref object of BBTree to BBLeaf[K,V] = ref object of BBTree[K,V])

type
  BBTree*[K,V] = ref object of RootObj
  # BBTree* = ref object of RootObj
  # BBLeaf[K,V] = ref object of BBTree[K,V]
  BBLeaf[K,V] = ref object of BBTree[K,V]
      key:   K                # the search key; must support the generic ``cmp`` proc
      val:   V                # the data value associated with the key, and stored in a node
  BBNode2[K,V] = ref object of BBLeaf[K,V]
      left:  BBTree[K,V]      # left subtree; may be nil
      right: BBTree[K,V]      # right subtree; may be nil
      size:  int              # the size of the (sub-)tree rooted in this node

func size[K,V](n: BBLeaf[K,V]):  int = return 1
func left[K,V](n: BBLeaf[K,V]):  BBTree[K,V] = return nil
# method left[K,V](n: BBLeaf[K,V]):  BBTree[K,V] = return nil
func right[K,V](n: BBLeaf[K,V]):  BBTree[K,V] = return nil

iterator inorder*[K,V](root: BBTree[K,V]): (K,V) =
    var curr = root
    while (not curr.isNil):
      curr = left(cast[BBLeaf[K,V]](curr))

var root : BBTree[int,int] = nil

for k,v in inorder(root):
    echo k, v

EDIT

just figured we can use a safer form for upcast instead of cast: use Subclass(a) instead of cast[Subclass](a) (which is too blunt; the former is OOP-safe)

type
  BBTree*[K,V] = ref object of RootObj
  BBLeaf[K,V] = ref object of BBTree[K,V]
      key:   K                # the search key; must support the generic ``cmp`` proc
      val:   V                # the data value associated with the key, and stored in a node
  BBNode2[K,V] = ref object of BBLeaf[K,V]
      left:  BBTree[K,V]      # left subtree; may be nil
      right: BBTree[K,V]      # right subtree; may be nil
      size:  int              # the size of the (sub-)tree rooted in this node

func size[K,V](n: BBLeaf[K,V]):  int = return 1
func left[K,V](n: BBLeaf[K,V]):  BBTree[K,V] = return nil
func right[K,V](n: BBLeaf[K,V]):  BBTree[K,V] = return nil

iterator inorder*[K,V](root: BBTree[K,V]): (K,V) =
    var curr = root
    while (not curr.isNil):
      # curr = left(cast[BBLeaf[K,V]](curr))
      curr = BBLeaf[K,V](curr).left

var root : BBTree[int,int] = nil

for k,v in inorder(root):
    echo k, v

@dcurrie
Copy link

dcurrie commented Jan 17, 2019

In general, curr can be a BBLeaf or a BBNode2, so the cast is not safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment