scala parameterized type on foldLeft -
given following signature parameterized method
def double[a <: byte](in:list[a]): list[a] = { //double values of list using foldleft //for ex. like: in.foldleft(list[a]())((r,c) => (2*c) :: r).reverse //but doesn't work! so.. } i trying following before tackling parameterized typed foldleft
def plaindouble[int](in:list[int]): list[int] = { in.foldleft(list[int]())((r:list[int], c:int) => { var k = 2*c println("r ["+r+"], c ["+c+"]") //want prepend list r // k :: r r }) } however, results in following error:
$scala fold_ex.scala error: overloaded method value * alternatives: (x: double)double <and> (x: float)float <and> (x: long)long <and> (x: scala.int)scala.int <and> (x: char)scala.int <and> (x: short)scala.int <and> (x: byte)scala.int cannot applied (int(in method plaindouble)) val k = 2*c ^ 1 error found if changed signature of def following:
def plaindouble(in:list[int]): list[int] = { ...} works , output :
val in = list(1,2,3,4,5) println("in "+ in + " plaindouble ["+plaindouble(in)+"]") is
in list(1, 2, 3, 4, 5) plaindouble [list(2, 4, 6, 8, 10)] apologies if missing obvious.
@dna correct in plaindouble[int] declares type parameter named int, has nothing actual type. attempt make non-generic still generic, in way not apparent.
but original problem?
scala> def double[a <: byte](in: list[a]): list[a] = in.foldleft(list.empty[a])((r,c) => (2*c) :: r) <console>:15: error: type mismatch; found : x$1.type (with underlying type int) required: def double[a <: byte](in: list[a]): list[a] = in.foldleft(list.empty[a])((r,c) => (2*c) :: r).reverse ^ the problem here 2 * c int, , not a. *(byte: byte) method on int returns int. hence message (with underlying type int). notice if cast a, compiles:
def double[a <: byte](in: list[a]): list[a] = in.foldleft(list.empty[a])((r,c) => (2*c).tobyte.asinstanceof[a] :: r).reverse notice how had call tobyte before casting a. isn't shining example of generics @ work, point incompatible return types causing error.
also notice how doesn't occur if remove 2 *:
def double[a <: byte](in: list[a]): list[a] = in.foldleft(list.empty[a])((r,c) => c :: r).reverse edit:
you might consider using numeric trait generics this.
import scala.math.numeric.implicits._ def double[a: numeric](in: list[a])(implicit i2a: int => a): list[a] = in.map(_ * 2) this relies on implicit numeric[a] being available numeric type (which there in scala.math.numeric object, pretty numeric type want). relies on implicit conversion being available int a, can write a * 2. can drop constraint using + instead:
def double[a: numeric](in: list[a]): list[a] = in.map(a => + a)
Comments
Post a Comment