gpt4 book ai didi

scala - 为什么不能推断泛型函数的参数类型?

转载 作者:行者123 更新时间:2023-12-04 12:38:56 24 4
gpt4 key购买 nike

在 Scala 2.11.7 中,具有以下 case 类和一个额外的 apply方法:

case class FieldValidator[T](key: String, isValid: T => Boolean, 
errorMessage: Option[String] = None)

object FieldValidator {
def apply[T](key: String, isValid: T => Boolean,
errorMessage: String): FieldValidator[T] = ???
}

当我尝试使用:
FieldValidator[String](key, v => !required || v.nonEmpty, "xxx")

我收到指向 v 的“缺少参数类型”编译错误.

当我明确指定 v 的类型时,它编译得很好,我什至可以跳过 apply 的泛型类型方法,即
FieldValidator(key, (v: String) => !required || v.nonEmpty, "xxx")

为什么不是 v的类型当只是 apply 的泛型类型时推断提供?

最佳答案

这不是关于泛型,而是重载和默认参数的问题。

首先,回想一下,自从 FieldValidatorcase -class,合成工厂方法

def apply(
key: String,
isValid: T => Boolean,
errorMessage: Option[String] = None
)

自动添加到伴随对象 FieldValidator .这导致 Field验证器具有两个具有默认参数和相同名称的通用方法。

这是一个较短的示例,其行为方式大致相同:
def foo[A](f: A => Boolean, x: Int = 0): Unit =  {}
def foo[A](f: A => Boolean, x: String): Unit = {}

foo[String](_.isEmpty)

结果是:

error: missing parameter type for expanded function ((x$1: ) => x$1.isEmpty)

 foo[String](_.isEmpty)
^


我无法确定到底出了什么问题,但本质上,您通过向编译器抛出三种不同类型的多态性而混淆了太多的歧义:
  • 重载:您有两个名称为 apply 的方法
  • 泛型:你的方法有一个泛型类型参数 [A]
  • 默认参数:您的 errorMessage ( x 在我较短的例子中)可以省略。

  • 总之,这使编译器可以在两个同名方法之间进行选择,这些方法具有不清楚的类型和不清楚的预期类型参数数量。虽然灵活性是好的,但太多的灵活性就是太多了,编译器放弃试图弄清楚你想要什么,并强制你明确指定每个参数的所有类型,而不依赖于推理。

    从理论上讲,它可以在这种特殊情况下解决这个问题,但这需要更复杂的推理算法和更多的回溯和反复试验(这会减慢一般情况下的编译速度)。你不希望编译器花半天时间玩 typesystem-sudoku,即使它理论上可以找到一个独特的解决方案。快速退出并显示错误消息是一个合理的选择。

    解决方法

    作为一种简单的解决方法,请考虑以允许编译器尽快消除歧义的方式重新排序参数。例如,将参数拆分为两个参数列表,其中两个 String s 首先出现,将使其明确:
    case class FieldValidator[T](
    key: String,
    isValid: T => Boolean,
    errorMessage: Option[String] = None
    )

    object FieldValidator {
    def apply[T]
    (key: String, errorMessage: String)
    (isValid: T => Boolean)
    : FieldValidator[T] = {
    ???
    }
    }

    val f = FieldValidator[String]("key", "err"){
    s => s.nonEmpty
    }

    关于scala - 为什么不能推断泛型函数的参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54347455/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com