问题标签 [type-inference]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1015 浏览

haskell - `([] ==) []` 的类型如何推断haskell?

这听起来很愚蠢,但我无法理解。为什么可以输入表达式 [] == [] 呢?更具体地说,哪个类型(在 Eq 类中)被推断为列表元素的类型?

在 ghci 会话中,我看到以下内容:

但约束也Eq [a]意味着Eq a,如下所示:

因此,在 []==[] 中,类型检查器必须假定列表元素是类 Eq 中的某个类型 a。但是哪一个?[] 的类型只是 [a],这肯定比 Eq a => [a] 更通用。

恕我直言,这应该是模棱两可的,至少在 Haskell 98 中(这就是我们正在谈论的)

0 投票
6 回答
6185 浏览

c# - C# 中可能的部分泛型类型推断?

我正在为我的 IoC 类库重写我的流利界面,当我重构一些代码以便通过基类共享一些通用功能时,我遇到了一个障碍。

注意:这是我想做的事情,而不是我必须做的事情。如果我不得不使用不同的语法,我会的,但如果有人知道如何让我的代码按照我想要的方式编译,那将是最受欢迎的。

我希望某些扩展方法可用于特定的基类,并且这些方法应该是通用的,具有一种通用类型,与方法的参数相关,但这些方法还应该返回与它们的特定后代相关的特定类型'被调用。

使用代码示例比上面的描述更好。

这是一个简单而完整的例子,说明什么不起作用

如果你编译这个,你会得到:

我想要的是扩展方法 ( Parameter<T>) 能够在ConcreteTypeRegistration和上调用DelegateRegistration,并且在这两种情况下,返回类型都应该与调用扩展的类型相匹配。

问题如下:

我想写:

但也Parameter<T>返回一个与它被调用的类型相同的对象,这意味着:

有什么办法可以欺骗编译器为我实现这一飞跃?

如果我向方法中添加两个泛型类型参数Parameter,类型推断会强制我要么提供两者,要么不提供,这意味着:

给了我这个:

这同样糟糕。

我可以轻松地重组类,甚至通过将它们引入层次结构来使方法成为非扩展方法,但我的问题是我是否可以避免为两个后代复制方法,并且以某种方式只声明一次, 对于基类。

让我重新表述一下。有没有办法更改上面第一个代码示例中的类,以便保留 Main-method 中的语法,而无需复制相关方法?

代码必须与 C# 3.0 和 4.0 兼容。


编辑:我不想将两个泛型类型参数都留给推理的原因是,对于某些服务,我想为一种类型的构造函数参数指定一个参数值,但传入一个后代值。目前,指定参数值和要调用的正确构造函数的匹配是使用参数的名称和类型完成的。

让我举个例子吧:

如果我将两者都留给类型推断,则参数类型将是FileStream,而不是Stream

0 投票
1 回答
255 浏览

scala - Scala类型推断问题

我只是在琢磨托尼莫里斯关于变质的出色练习,当时我正在思考在以下情况下发生了什么......

现在让我按如下方式调用此方法:

我想知道类型推断器是否确定了的类型_ => trueA => BooleanAny => Boolean。由于其输入参数Function1逆变的,因此以下两个编译都很好:

所以问题是,类型推断器提出#1 还是#2?

0 投票
1 回答
239 浏览

c# - 为什么泛型类型推断在这种情况下不起作用?

尝试在 LINQPad 中编译以下代码时:

我收到以下错误:

无法从用法中推断方法“System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)”的类型参数。尝试明确指定类型参数。

如果我使用类似 lambdad => GetProviderName(d)而不是方法组,它可以正常工作......我很惊讶,因为我确信编译器能够从方法组中推断出类型。范围内没有其他GetProviderName方法,并且输入和输出类型已明确定义,因此应该可以隐式转换为Func<DriveInfo, string>... 不是吗?

0 投票
4 回答
1094 浏览

java - Java 泛型类参数类型推断

给定接口:

在我的BasedOnOther<T, U extends BasedList<T>>用例中看起来非常难看。正是因为Ttype参数已经在BasedList<T>part中定义好了,所以“丑”就来自于T需要输入两次。

问题:是否可以让 Java 编译器从泛型类/接口定义中推断出泛型T类型?BasedList<T>

最终,我想使用如下界面:

哪里Y extends BasedList<SomeType>

反而:

哪里Y extends BasedList<SomeType>

更新:ColinD 建议

不可能创建一个实现,例如:

Where MemoryModel extends BasedList<SomeType>,这是需要的(因为它提供了其他方法)。

0 投票
4 回答
50263 浏览

java - 为什么将 Collections.emptySet() 与泛型一起使用在赋值中而不是作为方法参数?

所以,我有一个带有这样的构造函数的类:

我想FilterList用一个空集构造一个新对象。按照 Joshua Bloch 在他的《Effective Java》一书中的建议,我不想为空集创建一个新对象。我将Collections.emptySet()改为使用:

这给了我一个错误,抱怨这java.util.Set<java.lang.Object>不是java.util.Set<java.lang.Integer>. 好的,这个怎么样:

这也给了我一个错误!好的,这个怎么样:

嘿,它有效!但为什么?毕竟,Java 没有类型推断,这就是为什么如果你这样做Set<Integer> foo = new TreeSet()而不是Set<Integer> foo = new TreeSet<Integer>(). 但是Set<Integer> empty = Collections.emptySet();在没有警告的情况下工作。这是为什么?

0 投票
3 回答
4296 浏览

c++ - decltype 和括号

我不明白 FCD 第 148 页上示例的最后一行(第 7.6.1.2/4 节):

为什么括号在这里有所不同?它不应该只是double像上面的那行吗?

0 投票
2 回答
792 浏览

scala - 根据参数值和函数参数类型推断公共超类型

是否应该在不需要显式类型定义的情况下编译以下内容this

在我看来,类型应该能够推断出来。这只是 Scala 编译器的一个限制,还是有类型理论上的原因不能做到这一点?对于 Scala 类型推断器可以处理的内容,我还没有真正的感觉。

通过该方法工作:

  • B >: A根据定义
  • this具有 type PlayList[A],它是PlayList[B]since的子类型,B >: A并且 PlayList 在 中是协变的A
  • node有类型B,参数类型prefix
  • 函数参数finfoldr的第二个参数与 的第一个参数具有相同的类型(已声明Bfoldr
  • 因此suffix具有与 相同的类型this,因此特别是 a PlayList[A]。由于B >: A,suffix.prepNode()需要一个B.

我希望编译器看到typesuffix.prepNode(node)是合法的。只有当我在该调用中的调用或引用上明确指定类型时,它似乎才能做到这一点。nodeBfoldrthis

有趣的是,如果我将函数参数上的显式类型指定为(node: B, suffix: PlayList[B]),则方法调用的参数上仍然会生成类型不匹配错误suffix.prepNode(node)"found: B, required: A"

我正在使用 Scala 2.8 RC6。下面的完整示例,有问题的行是第 8 行。


编辑:第二次尝试通过编译步骤进行推理

  • 为清晰起见重命名,foldr采用 types 参数(T)((U, T) => T)。我们试图推断类型U和的值T
  • 函数的第一个参数和函数的第二个参数之间存在关系foldr——它们是相同的,T. (对丹尼尔的部分回答。)
  • 我们作为这些参数传递的对象的类型是this: PlayList[A]suffix: PlayList[B]
  • 因此,由于B >: A,最具体的常见超类型是PlayList[B]; 因此我们有T == PlayList[B]请注意,我们不需要 和 之间的任何关系UT推断这一点。

这是我卡住的地方:

  • 从编译错误信息中,推理者清楚地认为node具有类型B(即U == B)。
  • 如果不U == Bsuffix. (scala 编译器可以这样做吗?)
  • 如果推理的那一步发生了,那么它就会随之而来U == B,并且我们已经成功编译。那么是哪一步出错了呢?

编辑2:在重命名foldr上面的参数类型时,我错过U == A了定义,它是PlayList类的类型参数。我认为这仍然与上述步骤一致,因为我们在PlayList[B].

所以在调用站点,T == PlayList[B]作为最不常见的超类型的一些东西,并且根据接收者U == B的定义。foldr这似乎足够简洁,可以缩小到几个选项:

  • 编译器无法解析这些多种类型并计算B
  • 从返回类型到参数类型PlayList[B]的错误(怀疑)foldrprepNode
0 投票
1 回答
360 浏览

c# - 来自静态方法/调用者的类类型推断?

给定以下两个类:

以下列方式使用:

有什么方法可以推断出这样的类型T

0 投票
1 回答
985 浏览

visual-studio-2010 - 使用 C++0x decltype 返回值时返回局部变量或临时变量的地址

编辑:

这确实是编译器中的一个错误,我打开了一个缺陷并得到了以下响应。

您好 Motti,
感谢您提交此问题。如 stackoverflow 帖子中所述,这是我们的 decltype 实现中的一个错误。不幸的是,我们无法在 Visual Studio 的下一个版本中修复此错误,因为代码相对不常见,而且我们特别受资源限制。

原始问题如下


我正在使用 VS10 的 C++0x 功能,但遇到了以下问题。

我收到以下警告:

警告 C4172:返回局部变量或临时地址

但是,当我将原型更改为call旧样式时:

没关系,call不是模板函数时也可以(即使使用推导的返回类型)。

如果我查看ret它的类型std::map<int, int>(没有引用或指针)。

这是 VS10 中的错误还是我遗漏了什么。