【发布时间】:2020-05-24 00:34:22
【问题描述】:
我正在使用 Scala 2.13,并且我正在开发自己的 Reader monad。 monad的实现如下。
object ReaderMonad {
implicit def reader[From, To](f: From => To): Reader[From, To] = Reader(f)
case class Reader[From, To](f: From => To) {
def run(input: From): To =
f(input)
def map[NewTo](transformation: To => NewTo): Reader[From, NewTo] =
Reader(c => transformation(f(c)))
def flatMap[NewTo](transformation: To => Reader[From, NewTo]): Reader[From, NewTo] =
Reader(c => transformation(f(c)).run(c))
}
def pure[From, To](a: To): Reader[From, To] = Reader((c: From) => a)
}
使用这样的 monad,我正在为股票定义一个存储库。
trait StockRepository {
def findAll: Map[String, Double]
}
Stocks服务使用repository的实现,使用Reader monad注入repo依赖。
object Stocks {
def findAll: Reader[StockRepository, Map[String, Double]] =
(repo: StockRepository) => repo.findAll()
}
我的问题是,为什么我要在最后一个函数定义(repo: StockRepository) => repo.findAll() 中明确指定repo 参数类型?为什么 Scala 编译器不能为我隐式推断类型?
非常感谢。
【问题讨论】:
-
我不会在隐式转换中中继,而是使用显式
apply。查看 cats 之一。 -
谢谢,但您的评论没有回答我的问题:P
-
好的,编译器无法推断输入的类型。它只是看到一个与预期返回类型不匹配的函数,因此它没有任何方法可以推断。对您来说很明显,因为您希望应用隐式转换。但是编译器不能开始假设这么多东西。这就是隐式转换是一种不好的做法的原因之一,如果你希望它发生,那么它会更好。所以我建议使用
apply方法会有所帮助,因为这样编译器就可以推断输入类型。 -
抱歉,我没看懂你的第一条评论 :( 但是我还是不明白怎么给对象
Reader添加一个apply方法可以解决我的问题。你为什么不发布一个回答这样我可以接受吗?也许,你可以添加一个例子:)
标签: scala type-inference implicit reader-monad