Scala 磁铁图案和anonmyous函数:缺少参数类型错误

Scala 磁铁图案和anonmyous函数:缺少参数类型错误,scala,implicit,Scala,Implicit,我使用magnet模式调用正确的重载方法(flatMap),这取决于是否存在一些隐式参数 导入scala.language.implicitConversions 物体测试器{ 最终案例类别Foo[A](值:A){ def平面地图[B](类别:类别[A,B]):Foo[B]={ println(“cat”) f类(价值) } def flatMap[B](monkey:monkey[A,B]):Foo[B]={ println(“猴子”) monkey.f(值) } def映射[B](f:A=

我使用magnet模式调用正确的重载方法(
flatMap
),这取决于是否存在一些隐式参数

导入scala.language.implicitConversions
物体测试器{
最终案例类别Foo[A](值:A){
def平面地图[B](类别:类别[A,B]):Foo[B]={
println(“cat”)
f类(价值)
}
def flatMap[B](monkey:monkey[A,B]):Foo[B]={
println(“猴子”)
monkey.f(值)
}
def映射[B](f:A=>B):Foo[B]={
Foo(f(价值))
}
}
案例类香蕉()
猴子类[A,B](val f:A=>Foo[B])
对象猴子{
隐式def funcToMonkey[A,B](f:A=>Foo[B])(隐式i:Banana):Monkey[A,B]=新Monkey(f)
}
案例类Catnip()
类别Cat[A,B](val f:A=>Foo[B])
对象猫{
隐式def funcToCat[A,B](f:A=>Foo[B])(隐式i:Catnip):Cat[A,B]=新Cat(f)
}
}
对象主体{
进口测试仪_
def main(参数:数组[字符串])={
为了{

_我认为这不可行。为了避免必须为lambda提供参数类型,预期类型(因此这里的
flatMap
参数类型)必须是函数类型或SAM类型,而不仅仅是从函数类型(如
Cat
Monkey
进行隐式转换)的类型

在2.13之前,您也会遇到一个单独的问题,因为不允许重载该方法,但修复程序也不包括您的情况:

:

  • 其中一个重载至少应具有一种FunctionN类型:在本例中,应为 type是一个function n[Ti,?],其中Ti是参数类型(它们必须都是=:=),以及预期的 结果类型使用通配符省略。这不排除任何预期SAM的重载, 因为它们通过SAM转换符合函数类型

  • 或者:所有重载都期望相同类的SAM类型,但结果类型可能不同 (参数类型必须为=:=)

这两种方法都不适用于您(
Cat
Monkey
不是SAM类型,即使它们是SAM类型,也不会工作)。我尝试让
flatMap
直接使用隐式函数

import scala.language.implicitConversions
object Tester {
  final case class Foo[A](value: A) {
    def flatMap[B](f: A => Foo[B])(implicit i: Catnip): Foo[B] = {
      val cat: Cat[A, B] = f
      println("cat")
      cat.f(value)
    }

    def flatMap[B](f: A => Foo[B])(implicit i: Banana): Foo[B] = {
      val monkey: Monkey[A, B] = f
      println("monkey")
      monkey.f(value)
    }

    def map[B](f: A => B): Foo[B] = {
      Foo(f(value))
    }
  }

  case class Banana()
  class Monkey[A, B](val f: A => Foo[B])

  object Monkey {
    implicit def funcToMonkey[A, B](f: A => Foo[B])(implicit i: Banana): Monkey[A, B] = new Monkey(f)
  }
  case class Catnip()
  class Cat[A, B](val f: A => Foo[B])

  object Cat {
    implicit def funcToCat[A, B](f: A => Foo[B])(implicit i: Catnip): Cat[A, B] = new Cat(f)
  }

}

object Main {
  import Tester._
  implicit val cn = Catnip()
  def main(args: Array[String]) = {
    for {
      _ <- Foo(1)
      _ <- Foo("asdf")
    } yield ()
  }
}

是的,这就是为什么我要首先探索磁铁模式。似乎我需要探索其他选项。谢谢!
import scala.language.implicitConversions
object Tester {
  final case class Foo[A](value: A) {
    def flatMap[B](f: A => Foo[B])(implicit i: Catnip): Foo[B] = {
      val cat: Cat[A, B] = f
      println("cat")
      cat.f(value)
    }

    def flatMap[B](f: A => Foo[B])(implicit i: Banana): Foo[B] = {
      val monkey: Monkey[A, B] = f
      println("monkey")
      monkey.f(value)
    }

    def map[B](f: A => B): Foo[B] = {
      Foo(f(value))
    }
  }

  case class Banana()
  class Monkey[A, B](val f: A => Foo[B])

  object Monkey {
    implicit def funcToMonkey[A, B](f: A => Foo[B])(implicit i: Banana): Monkey[A, B] = new Monkey(f)
  }
  case class Catnip()
  class Cat[A, B](val f: A => Foo[B])

  object Cat {
    implicit def funcToCat[A, B](f: A => Foo[B])(implicit i: Catnip): Cat[A, B] = new Cat(f)
  }

}

object Main {
  import Tester._
  implicit val cn = Catnip()
  def main(args: Array[String]) = {
    for {
      _ <- Foo(1)
      _ <- Foo("asdf")
    } yield ()
  }
}
ambiguous reference to overloaded definition,
both method flatMap in class Foo of type [B](f: Int => Tester.Foo[B])(implicit i: Tester.Banana)Tester.Foo[B]
and  method flatMap in class Foo of type [B](f: Int => Tester.Foo[B])(implicit i: Tester.Catnip)Tester.Foo[B]
match argument types (Int => Tester.Foo[Unit])