Scala FlatMap和Applicative上下文边界会产生编译错误

问题描述 投票:2回答:1

我在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 ...

谁能解释这种行为?

scala functional-programming scala-cats
1个回答
6
投票

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]时没有这样的问题,因为你有单一的隐含。

© www.soinside.com 2019 - 2024. All rights reserved.