繁体   English   中英

Scala:Cats,OptionT [Future,T]和ApplicativeError

[英]Scala: Cats, OptionT[Future, T] and ApplicativeError

前段时间我开始使用Cats,发现OptionT在大多数情况下对Future[Option[T]]非常有用。 但我面对的一个缺点,使用AplicativeError我需要定义类型别名type FutureOption[T] = OptionT[Future, X]匹配F[_]所要求AplicativeError和明确指定作为我的表达式的类型FutureOption[T]

type FutureOption[T] = OptionT[Future, T] // definition to match F[_] kind

val x = OptionT.liftF(Future.failed(new Exception("error"))) : FutureOption[String] // need to specify type explicitly
x.recover {
  case NonFatal(e) => "fixed"
}

如果我删除表达式的类型定义和显式类型规范,则recover将不可用,因为OptionT[Future, T]F[_]不匹配,因此无法将其隐式转换为AplicativeErrorOps

不幸的是,下面的例子不起作用,因为没有recover方法。

val x = OptionT.liftF(Future.failed(new Exception("error")))
x.recover {
  case NonFatal(e) => "fixed"
}

有没有办法避免这种样板代码? 至少我想避免明确地将表达式类型指定为FutureOption[T]

除了其他答案,我建议您确保为您的构建启用了-Ypartial-unification

这是对类型构造函数的部分统一的修复。 您可以在此处找到有关此修复程序的更详细说明。

启用部分统一后,您在问题中提供的代码编译得很好。 请注意,如果您使用的是IDE(例如Intellij),您可能会收到“漏报”(代码加下划线标记为错误且代码完成无效),但scalac / sbt / gradle会将其编译得很好。

是的,至少有两种方法可以应对类型归属。

  • 使用lambdas类型(这可能是令人生畏的):

     val a: { type λ[A] = OptionT[Future, A] }#λ 
  • 使用类似投影仪的编译器插件,示例用法:

     val a: Lambda[A => OptionT[Future, A]] 

但如果你想打电话给Futurerecover ,你可以随时做到:

val x = OptionT.liftF(Future.failed(new Exception("error")))
x.value.recover ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM