为什么 F# 的类型推断不能处理这个问题? [英] Why can't F#'s type inference handle this?

查看:25
本文介绍了为什么 F# 的类型推断不能处理这个问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个FileInfo的序列,但我只关心它们的字符串名称,所以我想要一个字符串序列.起初我尝试过这样的事情:

I have a sequence of FileInfo, but I only care about their string names, so I want a sequence of string. At first I tried something like this:

Seq.map (fun fi -> fi.Name) fis

但是出于某种原因,F# 的类型推断不足以允许这样做,并且让我明确地为fi"指定了一个类型:

But for some reason, F#'s type inference isn't good enough to allow this, and made me explicitly give a type to "fi":

Seq.map (fun (fi : FileInfo) -> fi.Name) fis

为什么需要这个注解?如果知道 fis : seq 并且 Seq.map : ('a -> 'b) ->seq'a>->seq<'b>,那么它不应该推断出 lambda 表达式的类型是 FileInfo ->'b,然后,从 fi.Name : string 进一步推断其类型为 FileInfo ->字符串?

Why is this annotation required? If it is known that fis : seq<FileInfo> and that Seq.map : ('a -> 'b) -> seq<'a> -> seq<'b>, then shouldn't it infer that the type of the lambda expression is FileInfo -> 'b, and then, from fi.Name : string, further infer that its type is FileInfo -> string?

推荐答案

类型推断从左到右工作.这就是管道操作符有用的地方;如果你已经知道'fis'的类型,那么把它写成

Type inference works left-to-right. This is where the pipeline operator is useful; if you already know the type of 'fis', then write it as

fis |> Seq.map (fun fi -> fi.Name)

推理对您有用.

(一般来说,形式的表达

(In general, expressions of the form

o.Property
o.Method args

要求'o'的类型先验;对于大多数其他表达式,当一个类型没有被固定时,推理系统可以浮动一个约束",稍后可以解决这个问题,但对于这些情况,没有所有类型具有名为 P 的属性"形式的约束或'具有名为 M' 的方法的所有类型(如鸭子类型),可以推迟并稍后解决.所以你现在需要这些信息,否则推理会立即失败.)

require the type of 'o' to be known a priori; for most other expressions, when a type is not pinned down the inference system can 'float a constraint' along that can be solved later, but for these cases, there are no constraints of the form 'all types with a property named P' or 'all types with a method named M' (like duck typing) that can be postponed and solved later. So you need that info now, or inference fails immediately.)

另请参阅 F# 中的类型推断概述.

这篇关于为什么 F# 的类型推断不能处理这个问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆