Generic Programming in Scala

2019-01-29 03:35发布

问题:

Hi all I am fairly new to Scala coming from C#.

I am attempting to write my own version of accumulate ( fold) I am wondering why I am running into some issues with the following:

def accumulate[T](list : List[T], initial: T, f: (T, T) => T) : T = {
    @tailrec def loop[T](list: List[T], accum: T) : T =
      if(list.length == 0)
        accum
      else{
        val head : T = list.head
        val res : T = f(accum,head)
        loop[T](list.tail, res)
      }
    loop(list,initial)
  }

I am getting the following error:

type mismatch;
 found   : accum.type (with underlying type T)
 required: T
        val res : T = f(accum,head)
                        ^

I cant see how I have a type mismatch considering everything is type T.

Any thoughts / help would be appreciated.

Blair

回答1:

You should just remove type parameter from loop method. Replace loop[T] with loop.

With loop[T] you are creating new type parameter with name T, so T outside loop method and T in loop method are different type aliases with the same name.

It's called shadowing.

See these answers for similar problems:

  1. Scala type parameter error, not a member of type parameter
  2. Scala, Extend object with a generic trait
  3. Generic type inference in Scala


回答2:

The problem is that with the inner function loop you are defining a new type T that is shadowing the outer type T.

The compiler sees them as defining different types. If you simply remove the T type parameter from loop (including the recursive call loop(list.tail, res)) you should find it compiles just fine.