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

时间:2018-02-23 09:28:00

标签: scala scala-cats

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

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" }

2 个答案:

答案 0 :(得分:5)

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

这是对partial unification of type constructors的修正。您可以找到有关修复here的详细说明。

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

答案 1 :(得分:0)

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

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

    val a: { type λ[A] = OptionT[Future, A] }#λ
    
  • 使用像kind-projector这样的编译器插件,示例用法:

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

但如果您想致电Future的{​​{1}},您可以随时执行:

recover