2017-01-30 1 views
0

Étant donné:Définition de `implicit def` w/implicite?

trait Foo[A] 
class B 

puis les suivantes implicit def:

implicit def f[A](b: B)(implicit ev: Foo[A]): String = "foo" 

J'ai essayé de résoudre B => String implicitement, mais il n'a pas réussi à compiler:

scala> implicitly[B => String] 
<console>:15: error: No implicit view available from B => String. 
     implicitly[B => String] 
       ^

Je devine que la implicit Foo[A] jette une clé, pour ainsi dire, dans ma résolution implicite de B => String.

Comment est-ce que je peux ajuster l'argument de implicitly, par exemple B => String, de sorte que ce qui précède compile?

+1

Avez-vous essayé avant implicitly [Foo [B]] '(qui est requis pour votre conversion implicite)? – cchantep

+0

C'est un bon point - mon erreur. –

+1

BTW an 'implicite A => B' est une' conversion implicite' plutôt qu'une classe de type, ce qui conduit à l'avertissement correspondant (car il peut rapidement encombrer le code). J'utiliserais plutôt un trait 'MyFunT [A] extends (A => String)'. – cchantep

Répondre

1

code similaire en utilisant classe de types plutôt que la conversion implicite:

trait MyFunT[A] extends (A => String) 

object MyFunT { 
    /**Factory to easily define an instance from a fun */ 
    def apply[A](f: A => String): MyFunT[A] = new MyFunT[A] { 
    def apply(a: A): String = f(a) 
    } 
} 

implicit def foo[A](implicit ev: Foo[A]) = MyFunT[A] { a: A => /* do something with `a` and `ev` */ "foo" } 

Même si implicit s base/nécessitant d'autres implicit habituelles, je vous conseille de prendre soin de ne pas avoir « chaîne trop longue » à ce sujet .

+0

Pensez-vous que l'ajout de la fonction suivante à 'object Foo' serait aussi un bon choix:' def instance [A] (f: A => Foo [A]): ​​Foo [A] '? J'ai posé cette question après avoir relu le [Guide Shapeless] (https://github.com/underscoreio/shapeless-guide), où il mentionne la classe de type 'CsvEncoder': https://github.com/kevinmeredith/shapeless_book_exercises/ blob/master/src/main/scala/net/CsvEncoder.scala # L12-L15. –

+1

Une telle fonction d'usine est appelée 'apply' comme dans l'exemple – cchantep

+0

Après avoir lu votre réponse et vos commentaires utiles, je ne comprends pas pourquoi il est utile de faire en sorte que' MyFunT' étend ('= A> String)'. Qu'est-ce qui, si quelque chose, serait perdu si vous avez supprimé cet héritage? –