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