我有以下功能:
def function(i: Int): IO[Either[String, Option[Int]]] = ???
我想要一个形式的函数:
def foo(either: Either[String, Option[Int]]): IO[Either[String, Option[Int]]]
我希望它具有以下行为:
def foo1(either: Either[String, Option[Int]])
: IO[Either[String, Option[Int]]] = either match {
case Right(Some(i)) => bar(i)
case Right(None) => IO.pure(None.asRight)
case Left(s) => IO.pure(s.asLeft)
}
我想不那么明确地这样做,所以我尝试了EitherT:
def foo2(either: Either[String, Option[Int]]):
IO[Either[String, Option[Int]]] = {
val eitherT = for {
maybe <- EitherT.fromEither[IO](either)
int <- EitherT.fromOption(maybe, "???")
x <- EitherT(bar(int))
} yield x
eitherT.value
}
但这意味着Right(None)
将被Map到IO(Left("???"))
,这不是我想要的。
- 是否有
EitherT
的替代公式,但没有与foo1
实现相同的匹配表达式? - 更重要的是,使用
map/traverse/biTraverse/etc.
(与任何选项/选项都不匹配)的实现会是什么样子?
附:这里的目的是为以下类型定义一个“map”函数:
trait Lookup[F[_], K, A] {
def get(key: K): F[Either[FormatError, Option[A]]]
}
3条答案
按热度按时间mlmc2os51#
不带
match
mgdq6dx12#
nukf8bse3#
借助
MonadError
,我们可以:def foo
中只需要OptionT
EitherT
: