【问题标题】:Scala - how to create a single implicit that can be used for a type constructorScala - 如何创建可用于类型构造函数的单个隐式
【发布时间】:2015-09-24 00:15:04
【问题描述】:

我正在尝试编写一个方法,该方法在 StringOptionList 类型上使用 isEmpty 方法。这些类与该方法不共享共同的基本特征,因此我尝试将隐式 EmptyChecker 传递给它们:

  trait EmptyChecker[Field] {
    def isEmpty(data: Field): Boolean
  }

  implicit val StringEmptyChecker: EmptyChecker[String] = new EmptyChecker[String] {
    def isEmpty(string: String): Boolean = string.isEmpty
  }

  def printEmptiness[Field](field: Field)(implicit emptyChecker: EmptyChecker[Field]): Unit = {
    if (emptyChecker.isEmpty(field))
      println("Empty")
    else
      println("Not empty")
  }

  printEmptiness("abc") // Works fine

String 空检查器工作正常,但我在为 OptionList 等类型构造函数制作空检查器时遇到了问题。

例如,Option 不起作用:

  implicit val OptionChecker: EmptyChecker[Option[_]] = new EmptyChecker[Option[_]] {
    def isEmpty(option: Option[_]): Boolean = option.isEmpty
  }

  // Both fail compilation: "could not find implicit value for parameter emptyChecker: EmptyChecker[Some[Int]]
  printEmptiness(Some(3))
  printEmptiness[Option[Int]](Some(3))      

如果我使用特定的Option[Int] 检查器,效果会好一些,但有点丑:

  implicit val OptionIntChecker: EmptyChecker[Option[Int]] = new EmptyChecker[Option[Int]] {
    def isEmpty(optionInt: Option[Int]): Boolean = optionInt.isEmpty
  }

  // Fails like above:
  printEmptiness(Some(3))

  // Passes compilation:
  printEmptiness[Option[Int]](Some(3))

所以我的问题是:是否可以为每个 OptionList 类型创建一个 EmptyChecker 并让它们与我的方法一起使用,而无需在我调用它时显式声明类型?我正在尝试获得类型安全的鸭子打字效果。

我正在使用 scala 2.11.6。

提前致谢!

【问题讨论】:

    标签: scala implicit type-constructor


    【解决方案1】:

    问题的根源在于Some(1) 的类型是Some[Int],而不是Option[Int]。有几种方法可以解决这个问题;您可以使用类型归属显式向上转换表达式:printEmptiness(Some(3): Option[Int])。或者,您可以定义一个辅助方法来自动为您执行此操作,如果您使用的是 Scalaz,则提供了以下方法之一:

    import scalaz.syntax.std.option._
    printEmptiness(3.some)
    

    此外,如果您确实使用 Scalaz,您可能会发现查看 PlusEmpty/ApplicativePlus/MonadPlus 类型类很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-04
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多