tesis sistemas sistema recomendacion hacer como scala implicit

sistemas - Scala: Pasando un parámetro implícito implícitamente y el otro explícitamente. ¿Es posible?



sistema de recomendacion tesis (5)

Consideremos la función:

def foo(implicit a:Int, b:String) = println(a,b) .

Ahora, supongamos que hay una String e Int implicit val i1=1 ( implicit val i1=1 ) en el alcance, pero queremos pasar otro Int , implícito ( val i2=2 ) explícitamente a foo .

Cómo podemos hacer eso ? ¿Es posible? Gracias por leer.


  1. Llama explícitamente a foo(i2, s1) pero pierde el beneficio del uso de la implicit String
  2. Define def foo1(a: Int)(implicit b: String)=foo(a,b) y se llama foo1(i2)

En caso de que su método tenga muchos parámetros implícitos (a veces los tengo en mis proyectos) y a veces solo quiere especificar uno de ellos explícitamente y dejar que los otros se resuelvan implícitamente, puede escribir implicitly para cada otro parámetro como se muestra en mi otra respuesta. Pero a veces cambiará la firma de ese método o el parámetro explícito se encuentra en medio de esa lista de parámetros, luego puede hacer un código de cliente más legible con la siguiente construcción:

Supongamos que tiene algunos tipos y sus objetos ficticios implícitos:

trait I1; implicit object I1 extends I1 trait I2; implicit object I2 extends I2 trait I3; implicit object I3 extends I3 trait I4; implicit object I4 extends I4 trait I5; implicit object I5 extends I5 trait I6; implicit object I6 extends I6

Ahora tienes tu método foo1 que usa estas implicaciones:

def foo1(implicit i1: I1, i2: I2, i3: I3, i4: I4, i5: I5, i6: I6) { println(i1, i2, i3, i4, i5, i6) }

Ahora a menudo desea especificar explícitamente i4: I4 . Así que escribe:

val i4 = new I4 {} foo1(implicitly, implicitly, implicitly, i4, implicitly, implicitly)

¡Feo!
Con el siguiente (debe colocarse en un ámbito ajustado al método foo2 y tal vez se le foo2 nombre) envoltorio para todas las implicaciones:

object Implicits { def apply(i4: I4)(implicit i1: I1, i2: I2, i3: I3, i5: I5, i6: I6) = new Implicits(i1, i2, i3, i4, i5, i6) implicit def applying(implicit i1: I1, i2: I2, i3: I3, i4: I4, i5: I5, i6: I6) = new Implicits(i1, i2, i3, i4, i5, i6) } class Implicits(val i1: I1, val i2: I2, val i3: I3, val i4: I4, val i5: I5, val i6: I6)

y el método relacionado foo2 :

def foo2(implicit implicits: Implicits) = { import implicits._ println(i1, i2, i3, i4, i5, i6) }

ahora puedes llamar a foo2 lugar de foo1 la siguiente manera:

locally { foo2 // using implicit dummy objects I1, ..., I6 from above // or with explicit I4: val i4 = new I4 {} foo2(Implicits(i4)) }


Puede crear un nuevo ámbito interno y definir un nuevo valor implícito en él. La ventaja es que cuando tiene múltiples llamadas a funciones, de esta manera puede anular la implícita para todas ellas en un solo lugar:

def foo(implicit a:Int, b:String) = println(a,b). implicit val i = 1 implicit val s = "" foo // call with original implicits { implicit val i = 2 foo // call with a new Int implicit foo // call with a new Int implicit again }

Nota: el nuevo implícito debe tener el mismo nombre de variable que el original, para que lo oculte, de lo contrario obtendrá un error del compilador sobre los valores implícitos ambiguos.


Sé que es una vieja pregunta pero aún puede ser interesante. Una buena forma de hacerlo es usarlo implícitamente como valor predeterminado:

scala> def foo(a: Int = implicitly[Int], b: String = implicitly[String]) = println(a,b) scala> foo() (10,boo) scala> foo(50) (50,boo) scala> foo(b="bar") (10,bar)


Todo lo que puedo añadir es:

def foo(implicit a: Int, b: String) = println(a, b) implicit val i1 = 1 implicit val s = "" val i2 = 2 foo(i2, implicitly[String])