将完整类型提升为 monad 转换器
Lift full types into monad transformers
我有这 3 个 monad 转换器
type T[A] = OptionT[Future, A]
type E[A] = EitherT[Future, String, A]
type P[A] = OptionT[E, A]
我想将相应的完整类型(意思是完全对应的类型)提升到这些中。所以对于 T,我想将 Future[Option[Int]] 提升到其中。对于 E,我想提升 Future(Either[String, Int]),对于 P,我想提升 (Future[Either[String, Option[Int]]])。
我写了这段代码,它可以编译。除了我需要一种更简洁的方法来实现同样的事情。
val x : T[Int] = OptionT(Future(Option(10)))
val y : E[Int] = EitherT(Future(Right(10).asInstanceOf[Either[String, Int]]))
val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)).asInstanceOf[Either[String, Option[Int]]])))
我正在使用 Cats 1.1.0 和 Scala 2.12.3。
asInstanceOf 这件事很烦人。但如果我将最后一行更改为
val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
我收到这个编译器错误
[info] Compiling 1 Scala source to
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: no type parameters for method apply: (value: F[Either[A,B]])cats.data.EitherT[F,A,B] in object EitherT exist so that it can be applied to arguments (scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]])
[error] --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error] found : scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]]
[error] required: ?F[Either[?A,?B]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: type mismatch;
[error] found : scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]]
[error] required: F[Either[A,B]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: type mismatch;
[error] found : cats.data.EitherT[F,A,B]
[error] required: com.abhi.Transformers.E[Option[Int]]
[error] (which expands to) cats.data.EitherT[scala.concurrent.Future,String,Option[Int]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] three errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 0 s, completed Jul 11, 2018 9:46:21 PM
>
尝试为 Right 提供类型参数:
val z : P[Int] = OptionT(EitherT(Future(Right[String,Option[Int]](Option(10)))))
没有类型参数,当你做 Right(1)
scala 推断 Either[Nothing,Int]
.
您可以使用 import cats.implicits._
的隐式方法
那么你可以这样写
val z: P[Int] = OptionT(EitherT(Future(10.some.asRight[String])))
当然,您也可以编写自己的隐含函数
implicit class EitherFuture[A, B](val e: Future[A Either B]) extends AnyVal {
def asEitherT: EitherT[Future, A, B] = EitherT(e)
}
implicit class OptionEitherT[A](val e: EitherT[Future, String, Option[A]]) extends AnyVal {
def asOptionT = OptionT(e)
}
val zz: P[Int] = Future(10.some.asRight[String]).asEitherT.asOptionT
我有这 3 个 monad 转换器
type T[A] = OptionT[Future, A]
type E[A] = EitherT[Future, String, A]
type P[A] = OptionT[E, A]
我想将相应的完整类型(意思是完全对应的类型)提升到这些中。所以对于 T,我想将 Future[Option[Int]] 提升到其中。对于 E,我想提升 Future(Either[String, Int]),对于 P,我想提升 (Future[Either[String, Option[Int]]])。
我写了这段代码,它可以编译。除了我需要一种更简洁的方法来实现同样的事情。
val x : T[Int] = OptionT(Future(Option(10)))
val y : E[Int] = EitherT(Future(Right(10).asInstanceOf[Either[String, Int]]))
val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)).asInstanceOf[Either[String, Option[Int]]])))
我正在使用 Cats 1.1.0 和 Scala 2.12.3。
asInstanceOf 这件事很烦人。但如果我将最后一行更改为
val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
我收到这个编译器错误
[info] Compiling 1 Scala source to
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: no type parameters for method apply: (value: F[Either[A,B]])cats.data.EitherT[F,A,B] in object EitherT exist so that it can be applied to arguments (scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]])
[error] --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error] found : scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]]
[error] required: ?F[Either[?A,?B]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: type mismatch;
[error] found : scala.concurrent.Future[scala.util.Right[Nothing,Option[Int]]]
[error] required: F[Either[A,B]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] /Users//code/dallasscalacats/src/main/scala/com//Transformers.scala:32: type mismatch;
[error] found : cats.data.EitherT[F,A,B]
[error] required: com.abhi.Transformers.E[Option[Int]]
[error] (which expands to) cats.data.EitherT[scala.concurrent.Future,String,Option[Int]]
[error] val z : P[Int] = OptionT(EitherT(Future(Right(Option(10)))))
[error] ^
[error] three errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 0 s, completed Jul 11, 2018 9:46:21 PM
>
尝试为 Right 提供类型参数:
val z : P[Int] = OptionT(EitherT(Future(Right[String,Option[Int]](Option(10)))))
没有类型参数,当你做 Right(1)
scala 推断 Either[Nothing,Int]
.
您可以使用 import cats.implicits._
的隐式方法
那么你可以这样写
val z: P[Int] = OptionT(EitherT(Future(10.some.asRight[String])))
当然,您也可以编写自己的隐含函数
implicit class EitherFuture[A, B](val e: Future[A Either B]) extends AnyVal {
def asEitherT: EitherT[Future, A, B] = EitherT(e)
}
implicit class OptionEitherT[A](val e: EitherT[Future, String, Option[A]]) extends AnyVal {
def asOptionT = OptionT(e)
}
val zz: P[Int] = Future(10.some.asRight[String]).asEitherT.asOptionT