首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何结合Kleisli[M,A,C]和Kleisli[M,B,C]

如何结合Kleisli[M,A,C]和Kleisli[M,B,C]
EN

Stack Overflow用户
提问于 2016-03-17 14:33:37
回答 1查看 224关注 0票数 4

我遵循优秀书籍Reactive的设计,我需要将Kleisli与不同类型混合起来:

代码语言:javascript
复制
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)
  }

}

由于类型不对齐,我得到以下编译错误

代码语言:javascript
复制
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
              ^

修复该问题的最佳方法是创建一个

代码语言:javascript
复制
trait Context {
  def userRepo
  def projectRepo
}

用它污染UserServiceProjectService

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-17 16:04:19

您需要想出一些方法将输入类型组合成单个类型。其中一种方法是继承--您将拥有一个类型UserRepo with ProjectRepo,它是UserRepoProjectRepo的子类。另一种方法是组合,这里有一个元组(UserRepo, ProjectRepo)

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

代码语言:javascript
复制
for {
  user <- findByUserId.local[(UserRepo, ProjectRepo)](_._1)
  project <- findProjectById.local[(UserRepo, ProjectRepo)](_._2)
} yield (user, project)

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36063613

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档