Scala FlatMap 和应用上下文边界产生编译错误
Scala FlatMap and Applicative context boundaries yield compile error
我在 Scala 中做一些工作,遇到了 implicit
个实例的问题。让我们考虑以下示例:
import cats.{Applicative, FlatMap, Monad}
import cats.syntax.functor._
import cats.syntax.flatMap._
import cats.syntax.applicative._
class Test[F[_]: Monad] extends App{
val t1 = ().pure[F]
val t2 = ().pure[F]
def testFlatApplicative: F[Unit] =
for{
_ <- t1
_ <- t2
} yield ()
}
编译正常。但是由于 cats.Monad[F[_]]
声明如下:
@typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F]
我希望以下内容也能正常工作
import cats.{Applicative, FlatMap, Monad}
import cats.syntax.functor._
import cats.syntax.flatMap._
import cats.syntax.applicative._
class Test[F[_]: FlatMap : Applicative] extends App{
val t1 = ().pure[F]
val t2 = ().pure[F]
def testFlatApplicative: F[Unit] =
for{
_ <- t1
_ <- t2
} yield ()
}
但是编译失败,报错:
Error:(16, 12) value map is not a member of type parameter F[Unit]
_ <- t2
这很奇怪。 Apply
扩展 Functor
...
谁能解释这种行为?
class Test[F[_] : FlatMap : Applicative]
被脱糖为
class Test[F[_]](implicit flatMap: FlatMap[F], applicative: Applicative[F])
如果你对理解和语法进行脱糖处理,你就会发现问题所在:
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
Functor[F].map(t2)(_ => ())
)
Error: ambiguous implicit values:
both value applicative in class Test of type cats.Applicative[F]
and value flatMap in class Test of type cats.FlatMap[F]
match expected type cats.Functor[F]
因此您可以手动解决歧义:
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
applicative.map(t2)(_ => ())
)
或
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
flatMap.map(t2)(_ => ())
)
写class Test[F[_]: Monad]
就没有这个问题,因为你有单隐式。
我在 Scala 中做一些工作,遇到了 implicit
个实例的问题。让我们考虑以下示例:
import cats.{Applicative, FlatMap, Monad}
import cats.syntax.functor._
import cats.syntax.flatMap._
import cats.syntax.applicative._
class Test[F[_]: Monad] extends App{
val t1 = ().pure[F]
val t2 = ().pure[F]
def testFlatApplicative: F[Unit] =
for{
_ <- t1
_ <- t2
} yield ()
}
编译正常。但是由于 cats.Monad[F[_]]
声明如下:
@typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F]
我希望以下内容也能正常工作
import cats.{Applicative, FlatMap, Monad}
import cats.syntax.functor._
import cats.syntax.flatMap._
import cats.syntax.applicative._
class Test[F[_]: FlatMap : Applicative] extends App{
val t1 = ().pure[F]
val t2 = ().pure[F]
def testFlatApplicative: F[Unit] =
for{
_ <- t1
_ <- t2
} yield ()
}
但是编译失败,报错:
Error:(16, 12) value map is not a member of type parameter F[Unit]
_ <- t2
这很奇怪。 Apply
扩展 Functor
...
谁能解释这种行为?
class Test[F[_] : FlatMap : Applicative]
被脱糖为
class Test[F[_]](implicit flatMap: FlatMap[F], applicative: Applicative[F])
如果你对理解和语法进行脱糖处理,你就会发现问题所在:
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
Functor[F].map(t2)(_ => ())
)
Error: ambiguous implicit values:
both value applicative in class Test of type cats.Applicative[F]
and value flatMap in class Test of type cats.FlatMap[F]
match expected type cats.Functor[F]
因此您可以手动解决歧义:
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
applicative.map(t2)(_ => ())
)
或
def testFlatApplicative: F[Unit] =
FlatMap[F].flatMap(t1)(_ =>
flatMap.map(t2)(_ => ())
)
写class Test[F[_]: Monad]
就没有这个问题,因为你有单隐式。