Scala - 如何创建可用于类型构造函数的单个隐式
Scala - how to create a single implicit that can be used for a type constructor
我正在尝试编写一种方法,该方法在类型 String
、Option
和 List
上使用 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
空检查器工作正常,但我在为 Option
和 List
.
等类型构造函数制作空检查器时遇到了问题
例如,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))
所以我的问题是:是否可以为每个 Option
和 List
类型制作一个 EmptyChecker
并让它们使用我的方法而不需要显式声明类型每当我打电话给它?我正在尝试获得类型安全的鸭子打字效果。
我正在使用 scala 2.11.6。
提前致谢!
你的问题的根源是 Some(1)
的类型是 Some[Int]
,而不是 Option[Int]
。有几种方法可以解决这个问题;您可以使用类型归属显式向上转换表达式:printEmptiness(Some(3): Option[Int])
。或者,您可以定义一个辅助方法来自动为您执行此操作,如果您使用的是 Scalaz,则可以提供以下方法之一:
import scalaz.syntax.std.option._
printEmptiness(3.some)
此外,如果您使用 Scalaz,您可能会发现查看 PlusEmpty
/ApplicativePlus
/MonadPlus
类型 类 很有用。
我正在尝试编写一种方法,该方法在类型 String
、Option
和 List
上使用 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
空检查器工作正常,但我在为 Option
和 List
.
例如,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))
所以我的问题是:是否可以为每个 Option
和 List
类型制作一个 EmptyChecker
并让它们使用我的方法而不需要显式声明类型每当我打电话给它?我正在尝试获得类型安全的鸭子打字效果。
我正在使用 scala 2.11.6。
提前致谢!
你的问题的根源是 Some(1)
的类型是 Some[Int]
,而不是 Option[Int]
。有几种方法可以解决这个问题;您可以使用类型归属显式向上转换表达式:printEmptiness(Some(3): Option[Int])
。或者,您可以定义一个辅助方法来自动为您执行此操作,如果您使用的是 Scalaz,则可以提供以下方法之一:
import scalaz.syntax.std.option._
printEmptiness(3.some)
此外,如果您使用 Scalaz,您可能会发现查看 PlusEmpty
/ApplicativePlus
/MonadPlus
类型 类 很有用。