Как использовать неявно с функцией? - PullRequest
2 голосов
/ 24 ноября 2011

Привет, я прочитал интересный пост от Debasish о неявной функцииЯ написал этот код:

def find[C <: Business](id: String) = {
  collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))
}

, но он не может скомпилировать это сообщение компилятора:

could not find implicit value for parameter e: (com.mongodb.casbah.commons.Imports.DBObject) => C

в чем моя вина?Кто-нибудь может мне помочь?

ОБНОВЛЕНИЕ

Моя идея заключалась в следующем: поиск объявлен в признаке, ничего не знаю о DBObject, я не хочу ставить эту зависимость.

 trait BusinessRepository {
   def find[C <: Business](id: String): Option[C]
 }

class MongoBusinessRepository {

  val collection = ..

  def find[C <: Business](id: String): Option[C] = {
    collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))         
  }

  implicit def DBObject2Hotel(x: DBObject): Hotel = {
    // ... 
    // returning Hotel
  }
}

case class Hotel(...) extends Business(...)

Ответы [ 2 ]

7 голосов
/ 24 ноября 2011

implicitly - это просто удобный метод для поиска неявного значения, которое, как вы знаете, уже существует .Поэтому он не может быть скомпилирован, если в области действия нет такого неявного значения.

Возможный вариант использования - когда вы используете сокращенный синтаксис для границ контекста:

def find[C: Numeric](a: C, b: C): C = implicitly[Numeric[C]].plus(a, b)

Конечно, в этом примере, явная форма менее многословна

def find[C](a: C, b: C)(implicit n: Numeric[C]): C = n.plus(a, b)

Более подробные объяснения вы найдете в этой теме Stackoverflow .


Что, я думаю, вы имели в видуваш метод скорее

def find[C <: Business](id: String)(implicit fun: DBObject => C) =
  collection.findOneByID(id).map(fun)
1 голос
/ 24 ноября 2011

Я думаю, что проблема в том, что компилятор Scala пытается найти неявное определение функции DBObject => C и что единственное неявное определение, которое он может найти, это DBObject => Hotel, которое может быть решением, но оно не является строгим,С вашим решением компилятор не может знать, что должно быть C.

Возможно, вам следует рассмотреть возможность определения DBObject2Business и, таким образом, неявно определить функцию DBObject => Business или изменить свой дизайн, чтобы определить C в конкретном классе.

...