是否有类似 Collectable 类型类的东西?
Is there something like Collectable typeclass?
我注意到 Option
、OptionT
、fs2.Stream
等容器具有以下方法:
def collect[B](f: PartialFunction[A, B])(implicit F: Functor[F]): OptionT[F, B] =
OptionT(F.map(value)(_.collect(f)))
所以我很好奇是否有类似 Collectable
typeclass:
的东西
trait Collectable[F[_]] {
def collect[A, B](fa: F[A])(pf: PartialFunction[A, B]): F[B]
}
它对我来说似乎很有用,而且实现起来也很简单,但是无论如何 cats/scalaz
中已经包含了具有类似功能的东西吗?
Foldable 类型类似乎非常接近您想要的。它有一个方法 collectFirst
,签名如下:
def collectFirst[A, B](fa: F[A])(pf: PartialFunction[A, B]): Option[B] =
和一个奇怪的实现:
foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) =>
// trick from TraversableOnce,
// used to avoid calling both isDefined and apply (or calling lift)
val x = pf.applyOrElse(a, sentinel)
if (x.asInstanceOf[AnyRef] ne sentinel) Eval.now(Some(x.asInstanceOf[B]))
else lb
}.value
其中 sentinel
是一个奇怪的小函数,它本身总是 returns:
private val sentinel: Function1[Any, Any] =
new scala.runtime.AbstractFunction1[Any, Any]{
def apply(a: Any) = this
}
最后两个代码片段应该提供一些动机来避免多次重新实现 collectFirst
。
我注意到 Option
、OptionT
、fs2.Stream
等容器具有以下方法:
def collect[B](f: PartialFunction[A, B])(implicit F: Functor[F]): OptionT[F, B] =
OptionT(F.map(value)(_.collect(f)))
所以我很好奇是否有类似 Collectable
typeclass:
trait Collectable[F[_]] {
def collect[A, B](fa: F[A])(pf: PartialFunction[A, B]): F[B]
}
它对我来说似乎很有用,而且实现起来也很简单,但是无论如何 cats/scalaz
中已经包含了具有类似功能的东西吗?
Foldable 类型类似乎非常接近您想要的。它有一个方法 collectFirst
,签名如下:
def collectFirst[A, B](fa: F[A])(pf: PartialFunction[A, B]): Option[B] =
和一个奇怪的实现:
foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) =>
// trick from TraversableOnce,
// used to avoid calling both isDefined and apply (or calling lift)
val x = pf.applyOrElse(a, sentinel)
if (x.asInstanceOf[AnyRef] ne sentinel) Eval.now(Some(x.asInstanceOf[B]))
else lb
}.value
其中 sentinel
是一个奇怪的小函数,它本身总是 returns:
private val sentinel: Function1[Any, Any] =
new scala.runtime.AbstractFunction1[Any, Any]{
def apply(a: Any) = this
}
最后两个代码片段应该提供一些动机来避免多次重新实现 collectFirst
。