Scala 使用Int=>;筛选F[List[Int]];F[Boolean],其中F为泛型
我试图定义一个抽象代数,它允许我推迟选择将用于包装有效操作(IO、任务、未来等)的Monad,直到我运行程序Scala 使用Int=>;筛选F[List[Int]];F[Boolean],其中F为泛型,scala,generic-programming,scala-cats,Scala,Generic Programming,Scala Cats,我试图定义一个抽象代数,它允许我推迟选择将用于包装有效操作(IO、任务、未来等)的Monad,直到我运行程序 trait MyAlg[F[_]] def isValid(v: int): F[Boolean] def getElements(): F[List[Int]] def filterValidElements(vs: F[List[Int]]): F[List[Int]] 假设我需要在isValid中执行一些可能会产生副作用的操作,比如检查数据库 如果我可以将isVali
trait MyAlg[F[_]]
def isValid(v: int): F[Boolean]
def getElements(): F[List[Int]]
def filterValidElements(vs: F[List[Int]]): F[List[Int]]
假设我需要在isValid
中执行一些可能会产生副作用的操作,比如检查数据库
如果我可以将isValid
和getElements
抽象保留下来,例如,一个实现可以连接到数据库,另一个实现可以引用mock进行测试,但是定义一个通用的filterValidElements
,这样我就不需要为这两种情况重新实现相同的函数。大概是这样的:
def filterValidElements(es: F[List[Int]]]): F[List[Int]] =
es.map(
elems => elems.map(
e => (e, isValid(e))).collect{
case (e, F(true)) => e
})
但是,F
是泛型的,因此它不提供map
,也没有构造函数
当然,我不能明确地将F
设置为单子,例如
trait MyAlg[F: cats.Monad]
因为traits不能具有具有上下文边界的类型参数
有没有办法编写我的filterValidElements
函数,让isValid
abstract和F
generic
我对这种风格很陌生,所以我可能完全走错了方向 尝试添加隐式参数,指定您可以执行
映射
(即函子
)和纯
aka点
(即不变单体
)。例如,您可以使其应用
或Monad
import cats.{Functor, InvariantMonoidal}
import cats.syntax.functor._
import scala.language.higherKinds
trait MyAlg[F[_]] {
def isValid(v: Int): F[Boolean]
def getElements(): F[List[Int]]
def filterValidElements(es: F[List[Int]])(implicit functor: Functor[F], im: InvariantMonoidal[F]): F[List[Int]] =
es.map(
elems => elems.map(
e => (e, isValid(e))).collect{
case (e, fb) if fb == im.point(true) => e
})
}
这是非常接近工作。我必须将es.map更改为函子[F].map(es),然后它才能工作。谢谢。也许你没有导入cats.syntax.functor.\uu。如果您这样做了,您应该能够编写
es.map(..)
。一定要导入。