斯卡拉猫暧昧隐含值

问题描述 投票:7回答:1
import cats._
import cats.implicits._

trait Console[F[_]]{
  def readInput() : F[Int]
  def print(msg: String) : F[Unit]
} 

class Foo {
  def doFoo[F[_]: Monad](number: Int)(implicit C: Console[F]) : F[Unit] = {
    C.readInput().flatMap{input => 
      if (input == number) C.print("you won").map(_ => ())
      else if (input > number) C.print("you guessed too high").flatMap(_ => doFoo(number))
      else C.print("you guessed too low").flatMap(_ => doFoo(number))
    }
  }
} 

但我从编译器这种神秘的错误

cmd18.sc:5: ambiguous implicit values:
 both value catsStdInstancesForList in trait ListInstances of type => cats.Traverse[List] with cats.Alternative[List] with cats.Monad[List] with cats.CoflatMap[List]
 and value catsStdInstancesForVector in trait VectorInstances of type => cats.Traverse[Vector] with cats.Monad[Vector] with cats.Alternative[Vector] with cats.CoflatMap[Vector]
 match expected type cats.Monad[F]
else if (input > number) C.print("you guessed too high").flatMap(_ => dooFoo(number))
                                                                        ^
scala scala-cats cats-effect
1个回答
13
投票

问题是,你要价太高了Scala的类型推断的。它试图找出它需要doFoo[?](number)类型参数,虽然它很清楚地告诉我们作为人类,它已经被赋予F的背景下doFoo(number)出现在表达式中,编译器是没有那么聪明。

最简单的办法就是,明确规定了类型参数:

.flatMap(_ => doFoo[F](number))

如果您发现恼人的,你可以通过脱糖的F[_]: Monad约束的约束,这样就可以使ConsoleMonad实例明确的顺序帮助编译了一下:

import cats._
import cats.implicits._

trait Console[F[_]]{
  def readInput() : F[Int]
  def print(msg: String) : F[Unit]
} 

class Foo {
  def doFoo[F[_]](number: Int)(implicit C: Console[F], F: Monad[F]) : F[Unit] = {
    C.readInput().flatMap{input => 
      if (input == number) C.print("you won").map(_ => ())
      else if (input > number) C.print("you guessed too high").flatMap(_ => doFoo(number))
      else C.print("you guessed too low").flatMap(_ => doFoo(number))
    }
  }
}

在原来的版本,约束Monad背景下越来越脱到的隐含参数列表Monad[F]前来到一个隐含C: Console[F]参数,所以编译器试图首先解决它。在无糖以上版本,我颠倒了顺序,以便它会首先解决Console[F],这将让一切工作只是罚款当编译器都绕在试图推断FdoFoo(number)电话。

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