【发布时间】:2014-11-14 23:23:29
【问题描述】:
我正在阅读这篇关于 dependency injection in scala with Reader monad 的精彩文章。
原始示例运行良好,但我对UserRepository.get/find 的返回类型做了一些更改。原来是User,但我改成了Try[User]。
那代码就编译不出来了,我试了很多次,还是没有运气。
import scala.util.Try
import scalaz.Reader
case class User(email: String, supervisorId: Int, firstName: String, lastName: String)
trait UserRepository {
def get(id: Int): Try[User]
def find(username: String): Try[User]
}
trait Users {
def getUser(id: Int) = Reader((userRepository: UserRepository) =>
userRepository.get(id)
)
def findUser(username: String) = Reader((userRepository: UserRepository) =>
userRepository.find(username)
)
}
object UserInfo extends Users {
def userEmail(id: Int) = {
getUser(id) map (ut => ut.map(_.email))
}
def userInfo(username: String) =
for {
userTry <- findUser(username)
user <- userTry // !!!!!!!! compilation error
bossTry <- getUser(user.supervisorId)
boss <- bossTry // !!!!!!!! compilation error
} yield Map(
"fullName" -> s"${user.firstName} ${user.lastName}",
"email" -> s"${user.email}",
"boss" -> s"${boss.firstName} ${boss.lastName}"
)
}
编译错误是:
Error:(34, 12) type mismatch;
found : scala.util.Try[Nothing]
required: scalaz.Kleisli[scalaz.Id.Id,?,?]
user <- userTry
^
和
Error:(36, 12) type mismatch;
found : scala.util.Try[scala.collection.immutable.Map[String,String]]
required: scalaz.Kleisli[scalaz.Id.Id,?,?]
boss <- bossTry
^
我看了Kleisli.flatMap的文档(findUser和getUser的返回类型是Kleisli),它要求的参数类型是:
B => Kleisli[M, A, C]
因为Try 不会是Kleisli,所以会有这样的错误。
我不知道如何处理它。我可以在这里使用scala.util.Try 吗?我怎样才能把它变成KLeisli 类型?我怎样才能使这个例子工作?
【问题讨论】:
标签: scala dependency-injection monads scalaz