0

In my Test.scala, I defined a Trait and Object for incrementing a number first. Note that I'm using part of the RNG code based on the "Random Number Generator" lesson in Functional Programming in Scala.

trait NumberInc {
  def currentInt: Int
  def nextInt: (Int, NumberInc)
}

object NumberInc {
  def simple(seed: Int): NumberInc = new NumberInc {
    def currentInt: Int = seed
    def nextInt: (Int, NumberInc) = (seed + 1, simple(seed + 1))
  }
}

Then, within my "Test" object's foo() method, I perform the following logic:

def foo() { 

  var numberInc = NumberInc.simple(0)

  def bar() = { 
     baz(numberInc.currentInt)
     var (_, numberInc) = numberInc.nextInt /* Error Line */

  }

}

But I'm getting this error on the above error line.

[error] forward reference extends over definition of variable numberInc

I found this answer to be helpful, but I'm not sure how it applies to my above code.

Community
  • 1
  • 1
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384

2 Answers2

2

When you call the method numberInc.nextInt it is not referencing the NumberInc instance defined a few lines above. It is trying to do a recursive definition since you used the same name for the new variable. If you delete the whole line var numberInc = NumberInc.simple(0) you get the same error.

Dave L.
  • 9,595
  • 7
  • 43
  • 69
  • What do you mean by `you used the same name for the new variable`? Could you please tell me how to resolve this issue and use `numberInc` as a **var**? – Kevin Meredith Oct 24 '13 at 14:03
  • Just change the line to `var (_, numberInc2) = numberInc.nextInt` for example. – Dave L. Oct 24 '13 at 14:05
  • But, I'll be calling `bar()` multiple times, so I want to use the **current** NumberInc object. Using `(_, numberInc2) = numberInc.nextInt` won't let me re-assign the `numberInc` to the next NumberInc obj, right? – Kevin Meredith Oct 24 '13 at 14:07
  • Well maybe return the next `NumberInc` from `bar`? And then assign `numberInc` to the result of `bar`...Hard to say just based on pseudo code. – Dave L. Oct 24 '13 at 14:16
0

You defined a new variable with the name numberInc instead of changing the old one. Here is one way to fix that.

trait NumberInc {
  def currentInt: Int
  def nextInt: NumberInc
}

object NumberInc {
  def simple(seed: Int): NumberInc = new NumberInc {
    def currentInt: Int = seed
    def nextInt: NumberInc = simple(seed + 1)
  }
}

def foo() { 
  var numberInc = NumberInc.simple(0)

  def bar() = { 
     baz(numberInc.currentInt)
     numberInc = numberInc.nextInt
  }
}

But you could also use an iterable instead.

def foo() { 
  var iter = Iterator.from(0).toIterable

  def bar() = { 
     baz(iter.head)
     iter = iter.tail
  }
}
Tesseract
  • 8,049
  • 2
  • 20
  • 37