gpt4 book ai didi

scala - 如何组合 Kleisli[M, A, C] 和 Kleisli[M, B, C]

转载 作者:行者123 更新时间:2023-12-01 00:43:48 25 4
gpt4 key购买 nike

我遵循优秀书籍Reactive Domain Modeling的设计,我需要混合Kleisli不同类型:

object CombinedKleisli {
type User = String
type Project = String

trait UserRepo
trait ProjectRepo
trait UserService {
def findByUserId : Kleisli[Future, UserRepo, User]
}
trait ProjectService {
def findProjectById : Kleisli[Future, ProjectRepo, Project]
}
trait ComposedService extends UserService with ProjectService {
for {
user <- findByUserId
project <- findProjectById
} yield (user, project)
}

}

由于类型不对齐,我收到以下编译错误
Error:(28, 15) type mismatch;
found : scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.ProjectRepo,(domain.service.ServiceTest.User, domain.service.ServiceTest.Project)]
(which expands to) scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.ProjectRepo,(String, String)]
required: scalaz.Kleisli[scala.concurrent.Future,domain.service.ServiceTest.UserRepo,?]
project <- findProjectById
^

解决这个问题的最佳方法是什么,创建一个
trait Context {
def userRepo
def projectRepo
}

和污染 UserServiceProjectService用它 ?

最佳答案

您需要想出某种方法将输入类型合并为一个类型。一种方法是继承——你有一个类型 UserRepo with ProjectRepo那是 UserRepo 的子类和 ProjectRepo .另一种方法是组合,你有一个元组 (UserRepo, ProjectRepo) .

在这两种情况下,您通常会使用 local “扩展”每个箭头的输入类型,以便您可以在 for 中组合它们-理解:

for {
user <- findByUserId.local[(UserRepo, ProjectRepo)](_._1)
project <- findProjectById.local[(UserRepo, ProjectRepo)](_._2)
} yield (user, project)

这里 (UserRepo, ProjectRepo) type 参数参数指定新的输入类型,值参数(例如 _._1 )指定如何从新输入类型获取原始箭头的输入类型。

关于scala - 如何组合 Kleisli[M, A, C] 和 Kleisli[M, B, C],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36063613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com