gpt4 book ai didi

scala - 为什么在 F[_] 参数预期有效的地方传递 Int?

转载 作者:行者123 更新时间:2023-12-03 22:23:09 25 4
gpt4 key购买 nike

假设我们有一个函数:

def bar[F[_], A](x: F[A], y: F[A]) = null
以下所有行为都是明确的:
bar(List(1, 2, 3), List(1)) // compiles ok
bar(List(1), Some(1)) // doesn't compile
但,
bar(1, List(1)) // compiles ok
bar(1, 1) // compiles ok
为什么?
附言来自 FSiS Part 1 - Type Constructors, Functors, and Kind Projector 的示例

最佳答案

我认为您遇到了类型推断系统的限制。为了阐明这一点,让我们看看当我们重新定义它以获得更有用的输出时会发生什么:

class Bar[F[_], A](x: F[A], y: F[A]) {}
res0: Bar[List,Int] = Bar@69f1a286
new Bar(List(1,2,3), List(1))
res1: Bar[Any,Int] = Bar@7b139eab
new Bar(List(1), 1)
res2: Bar[Any,Int] = Bar@456be73c
new Bar(List(1), Some(1))
<console>:12: error: inferred kinds of the type arguments (Product with java.io.Serializable,Int) do not conform to the expected kinds of the type parameters (type F,type A) in class Bar.
Product with java.io.Serializable's type parameters do not match type F's expected parameters:
<refinement of Product with java.io.Serializable> has no type parameters, but type F has one
new Bar(List(1), Some(1))
^
<console>:12: error: type mismatch;
found : List[Int]
required: F[A]
new Bar(List(1), Some(1))
^
<console>:12: error: type mismatch;
found : Some[Int]
required: F[A]
new Bar(List(1), Some(1))

在第一个示例中,我们有一个 Bar[List, Int] ,这很有意义,我们传入了两个 List[Int]

在第二个和第三个中,我们有一个 Bar[Any, Int] 。这就是它变得奇怪的地方。请记住, AnyAnyVal(Java 原语的 Scala 等价物的父代)和 AnyRef(Java 对象的 Scala 等价物)的父代(参见 Scala Documentation 以获得进一步的解释)。

Scala 的类型推断已经决定这个 Bar 的构造函数应该接受 AnyFIntA 。由于 Any 确实是 ListInt 的父级,这很好。 List 确实被参数化为 [Int] ,所以没问题。奇怪的是 Scala 可以说 Int 也是 Any[Int] 类型。我对那部分没有很好的解释。

对于最后一个,老实说,这就是我感到困惑的地方,我不得不怀疑这是否是一个错误。出于某种原因,即使 ListSome 都是 Any 的子代,并且都使用 Int 参数化,但它不允许这样做。恐怕我不太精通编译器推理方法的复杂性,但就其值(value)而言,明确指定这些参数有效:
new Bar[Any,Int](List(1), Some(1))
res14: Bar[Any,Int] = Bar@36238b12

对我来说,这表明类型推断系统无法正确推断类型,或者推断的类型不正确。

关于scala - 为什么在 F[_] 参数预期有效的地方传递 Int?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32875853/

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