这是一个很好的示例:
import cats.data.ReaderT
import cats.instances.option._
...
def f1:ReaderT[Option, Service, Int] =
ReaderT(service => for {
res <- Some(10)
} yield res )
这是一个未编译的示例:
def f2:ReaderT[Option, Service, Int] =
for {
res <- ReaderT((_:Service) => Some(10))
} yield res
我收到以下错误:
错误:(53,11)找不到参数F的隐式值:cats.Functor [Some] res <-ReaderT((:Service)=> Some(10))错误:( 53,11 )没有足够的参数作为方法映射:(隐式F:cats.Functor [Some])cats.data.Kleisli [Some,com.savdev.Service,Int]。未指定值参数F. res <-ReaderT((:Service)=> Some(10))
要解决第二个示例中的错误,我必须返回not Some
,但是返回Option
,它是以下项的父级Some
:
def f2:ReaderT[Option, Service, Int] =
for {
res <- ReaderT((_:Service) => Option(10))
} yield res
你能解释一下吗?为什么在第一个示例中,return Some
(但不是Option
)工作正常。为什么在第二个示例中Some
同时不返回返回值?Scala编译器是否可以选择编译案例,如第二个示例中所示?或其他解决方案。
在第一种情况下,它map
直接调用on Some
,已知该方法会返回Option
(子类Some
为的普通多态性Option
),然后继续进行查找Functor[Option]
。
在第二种情况下,函数的返回类型被推断为Some[Int]
,并且编译器尝试查找Functor[Some]
typeclass的实例以调用方法Reader
(具有typeclass的即席多态性Functor
),但这失败了,因为没有的函子Some
。
主要问题在于,这Some
不仅是类型实例的构造函数(例如,Option
在Haskell中),而且实际上是(主要是无用的)类型实例的构造函数Some
,有时会弄乱类型推断/隐式解析度。
如果要强制执行所产生的类型Option[Int]
,使用Option(10)
构造Some
或Option.empty
构建None
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句