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

查看:42
本文介绍了为什么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<FileInfo>Seq.map : ('a -> 'b) -> seq<'a> -> seq<'b>,那么是否不应该推断lambda表达式的类型为FileInfo -> 'b,然后从fi.Name : string进一步推断其类型为FileInfo -> string?

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天全站免登陆