我有这样的代数
object Algebra {
case class Product(id: String, description: String)
case class ShoppingCart(id: String, products: List[Product])
trait ShoppingCarts[F[_]] {
def create(id: String): F[Unit]
def get(id: String): F[ShoppingCart]
def find(id: String): F[Option[ShoppingCart]]
}
}
我提出了以下实现。但我想知道是否有可能在trait本身中实现它作为泛型方法。我试图将上下文绑定到函子以访问Map,但这不是有效的构造。
override def get(id: String): ScRepoState[ShoppingCart] =
find(id).flatMap {
case Some(sc) => sc.pure[ScRepoState]
case None => create(id) *> get(id)
}
另一个问题是实现addmany()metdhod。我有这样的东西
def addMany[F[_] : Monad](cartId: String, products: List[Product])(implicit shoppingCarts: ShoppingCarts[F]): F[ShoppingCart] = {
for {
cart <- shoppingCarts.get(cartId)
product <- products.pure[F]
newCart <- product.traverse(product => shoppingCarts.add(cart, product))
} yield newCart
}
我挣扎着如何在一个理解块中混合不同的 Package
1条答案
按热度按时间jq6vz3qz1#
但我想知道是否有可能在trait本身中实现它作为泛型方法。
不完全是。Scala2不允许traits有参数,但是可以使用抽象类。您既可以不完全使用trait,也可以使用一个包含所有可派生实现的默认类,例如:
这是我比较喜欢的方法,但也有其他直接改变特征的方法。
您可以添加
Monad
方法的参数:这与我们在抽象类示例b/c的使用站点中所做的非常不同
ShoppingCarts
将被迫使用monad而不是构建站点,并且实现者如果想要重写该方法,就必须完全复制签名,即使这样做Monad[F]
未使用。您还可以模拟trait参数对抽象隐式def的作用:
这是可行的,但是在实现
F
成员。我挣扎着如何在一个理解块中混合不同的 Package
你没有。不允许混合。不要用它来理解列表,只能用它来理解
F
. 在一些更复杂的情况下,您可能需要嵌套以获得理解,或者使用monad转换器,但是这里您只需要在f中工作。我也不知道什么是回报类型的add
,但假设是F[ShoppingCart]
:下一次请单独问第二个问题。