Scala型推理混淆

Scala型推理混淆,scala,Scala,代码来自Scala中的函数式编程,IDE抱怨来自模式匹配的recv应该只接收Nothing type作为其参数,但实际上type是Any。但是,它仍然通过编译。我还认为recv将被推断为run[F[?],A]函数的请求[F[?],Nothing,A]。这里发生了什么事?Scala似乎有一些动态特性。它可以推断出运行时中的I类型,但这不是真的 根据请求的定义,我们知道expr的类型是F[I],recv的类型是I=>IO[F,A]。根据Run的定义,我们知道Rexpr将具有类型I,Run[F]。所以

代码来自Scala中的函数式编程,IDE抱怨来自模式匹配的recv应该只接收Nothing type作为其参数,但实际上type是Any。但是,它仍然通过编译。我还认为recv将被推断为run[F[?],A]函数的请求[F[?],Nothing,A]。这里发生了什么事?Scala似乎有一些动态特性。它可以推断出运行时中的I类型,但这不是真的

根据请求的定义,我们知道expr的类型是F[I],recv的类型是I=>IO[F,A]。根据Run的定义,我们知道Rexpr将具有类型I,Run[F]。所以e有I型,recv是一个接受I型参数的函数

这告诉我们,尽管我们对I一无所知,但recve的类型还是很好的

我还认为recv将被推断为run[F[?],A]函数的请求[F[?],Nothing,A]


否,recv具有类型I=>IO[F,A],其中F和A是run定义中的类型变量,I是创建请求对象时用作请求的第二个类型参数的类型。

您的IDE是否可能是IntelliJ?它有一点标记不存在的类型错误的诀窍。@sepp2k是的,我现在有一个更清楚的问题:我需要问另一个问题。我觉得这个不够清楚,非常想你!你知道这个更好的问题吗:
  trait IO[F[_], +A]
  case class Pure[F[_], +A](get: A) extends IO[F,A]
  case class Request[F[_], I, +A](expr: F[I], receive: I => IO[F,A]) extends IO[F,A]

  trait Console[A]
  case object ReadLine extends Console[Option[String]]
  case class PrintLine(s: String) extends Console[Unit]

  trait Run[F[_]] {
    def apply[A](expr: F[A]): (A, Run[F])
  }

  object IO {
    @annotation.tailrec
    def run[F[_],A](R: Run[F])(io: IO[F,A]): A = io match {
      case Pure(a) => a
      case Request(expr,recv) =>
        R(expr) match { case (e,r2) => println(e.getClass); run(r2)(recv(e)) }
    }
  }