我尝试创建一些简单的自定义字符串插值器,只要我不尝试使用类型参数,我就会成功。
import scala.concurrent.Future
object StringImplicits {
implicit class FailureStringContext (val sc : StringContext) extends AnyVal {
// This WORKS, but it's specific to Future :(
def fail[T](args : Any*): Future[T] = {
val orig = sc.s (args : _*)
Future.exception[T](new Exception(orig))
}
// I want this to work for Option,Try,Future!!
def fail[M,T](args:Any*): M[T] = {
val orig = sc.s (args : _*)
// Obviously does not work..
M match {
case Future => Future.exception(new Exception(orig))
case Option => None
case Try => Failure(new Exception(orig))
case _ => ???
}
}
}
}
我能让这个工作吗?我不能使用参数多态,因为我不是定义这三种类型的那种。
该伪代码模式匹配的类型级别中的等价物是什么?
最新的尝试
我最近的尝试是暗中使用,但我没有这样隐含!我实际上有兴趣根据类型推断抓住编译器要我返回的类型。
def fail[T, M[T]](args:Any*): M[T] = {
val orig = sc.s(args: _*)
implicitly[M[T]] match {
case _:Future[T] => Future.exception(new Exception(orig))
case _ => ???
}
}
<console>:18: error: could not find implicit value for parameter e: M[T]
implicitly[M[T]] match {
^
<console>:19: error: value exception is not a member of object scala.concurrent.Future
case _: Future[T] => Future.exception(new Exception(orig))
^
答案 0 :(得分:1)
在我看来,最简单的是依靠良好的旧重载:只需为要处理的每种类型定义不同的重载。
现在当然,存在使用相同签名进行不同重载的问题,并且像在scala中一样,您可以使用技巧来解决它们。在这里,我们将添加虚拟隐式参数,以强制每个重载具有不同的签名。不漂亮,但它可以工作,在这种情况下就足够了。
import scala.concurrent.Future
import scala.util.{Try, Failure}
implicit class FailureStringContext (val sc : StringContext) extends AnyVal {
def fail[T](args : Any*): Future[T] = {
Future.failed[T](new Exception(sc.s (args : _*)))
}
def fail[T](args : Any*)(implicit dummy: DummyImplicit): Option[T] = {
Option.empty[T]
}
def fail[T](args : Any*)(implicit dummy: DummyImplicit, dummy2: DummyImplicit): Try[T] = {
Failure[T](new Exception(sc.s (args : _*)))
}
}
tada:
scala> fail"oops": Option[String]
res6: Option[String] = None
scala> fail"oops": Future[String]
res7: scala.concurrent.Future[String] = scala.concurrent.impl.Promise$KeptPromise@6fc1a8f6
scala> fail"oops": Try[String]
res8: scala.util.Try[String] = Failure(java.lang.Exception: oops)