Scala разрешение классов типов - PullRequest
1 голос
/ 22 апреля 2020

Я видел, как это решение работало в прошлом, поэтому я не уверен, что делаю неправильно. Подумайте над ответом Как работает разрешение классов типов в scala?

Из него я сделал этот код:

import org.specs2.mutable.Specification

case class OptionFinder[A](isOption: Boolean)

object OptionFinder extends LowerPriority {
  implicit def hitOption[A]: OptionFinder[Option[A]] = OptionFinder(true)
}

trait LowerPriority {
  implicit def notOption[A]: OptionFinder[A] = OptionFinder(false)
}

object OptionFinderSpec extends Specification {
  "OptionFinder" should {

    "find Options" in {
      def myFunction[A](value: A)(implicit optionFinder: OptionFinder[A]): Boolean = {
        optionFinder.isOption
      }

      myFunction(5) must beFalse
      myFunction(None) must beTrue
      myFunction(Some(5)) must beTrue
    }
  }
}

Насколько я понимаю, все тесты должен пройти. По какой-то причине оба myFunction(None) must beTrue и myFunction(Some(5)) must beTrue терпят неудачу

Что я делаю не так?

1 Ответ

2 голосов
/ 22 апреля 2020

Компилятор распознает ваши параметры в этих двух случаях как None и Some вместо Option. Сложно иметь неявный экземпляр для «любого А», потому что тогда вы можете довольно часто сталкиваться с этой ситуацией, когда вы ожидаете, что будет использоваться какой-то более конкретный тип c (например, Option[A]), но случайно вернетесь к неявный для обобщенного типа c (в данном случае A), и компилятор не может действительно знать, что это не то, что вы хотели.

Итак, это будет работать:

myFunction(Option.empty) must beTrue
myFunction(Option(5)) must beTrue

Это также будет работать:

implicit def hitOption[A]: OptionFinder[Option[A]] = OptionFinder(true)
implicit def hitOptionN: OptionFinder[None.type] = OptionFinder(true)
implicit def hitOptionS[A]: OptionFinder[Some[A]] = OptionFinder(true)
...
myFunction(None) must beTrue
myFunction(Some(5)) must beTrue

Вы можете винить в этом дизайн Option. Я почти уверен, что каждый Scala разработчик хотя бы раз сталкивался с проблемой «Опция ожидалась, но нашла Некоторые». Если вы построите их, используя empty и apply, вы будете в безопасности.

...