As many other people, I've tried to write an Either type for my own purposes (peeking into others' solutions). Here is a piece of code that illustrates the problem I encountered:
type EitherSide = enum
ok, err
type Either[L, R] = ref object
case kind: EitherSide
of ok: left: L
else: right: R
method right[L, R]( r: R ) : Either[L, R] =
Either[L, R]( kind = err, right = r )
proc myfunc() : Either[int, string] =
right( "Not implemented yet!" )
But I get the error message Error: cannot instantiate: 'L' from the compiler. Now, if I was the compiler, I could easily infer the instantiation of L as int from the return type of the function myfunc(), why can't the nim compiler?I don't see how compiler can instantiate right method. The L is not bound to anything at al. You can do it only explicitly:
proc myfunc() : Either[int, string] =
right[int, string]( "Not implemented yet!" )
blah blah blah:
type EitherSide = enum
ok, err
type Either[L, R] = object
case kind: EitherSide
of ok:
mleft: L
else:
mright: R
proc `right=`*[L,R](this: var Either[L, R]; value: R): void =
this.kind = err
this.mright = value
proc `left=`*[L,R](this: var Either[L, R]; value: L): void =
this.kind = ok
this.mleft = value
proc right*[L,R](this: Either[L, R]): R =
this.mright
proc left*[L,R](this: Either[L, R]): L =
this.mleft
proc myfunc() : Either[int, string] =
result.right = "Not implemented yet!"
let x = myfunc()
echo x.right
ther is a languare that supports what Ikalman does, it is scala. Here an excerpt from the repl.
scala> val a = Left(123)
a: scala.util.Left[Int,Nothing] = Left(123)
scala> val b = Right("hallo")
b: scala.util.Right[Nothing,String] = Right(hallo)
scala> var c : Either[Int,String] = null
c: Either[Int,String] = null
scala> c = b
c: Either[Int,String] = Right(hallo)
scala> c = a
c: Either[Int,String] = Left(123)
scala>
Scala has the Nothing type and type covariance. Type covariance can only work on reference types, and nim simply does not work that way.