F# 中序列表达式的类型推断

2024-02-13

我想我不太明白 F# 如何推断序列表达式中的类型,以及为什么即使我直接从“seq”指定元素的类型也无法正确识别类型。

在以下 F# 代码中,我们有一个基类 A 和两个派生类 B 和 C:

type A(x) =
    member a.X = x

type B(x) =
    inherit A(x)

type C(x) =
    inherit A(x)

如果我尝试在简单的序列表达式中“生成”它们的实例,则会出现两个错误:

// Doesn't work, but it makes sense.
let testSeq = seq {
    yield A(0)
    yield B(1) // Error, expected type: A
    yield C(2) // Error, expected type: A
}

这是有道理的,因为推断“常见”类型可能并不是那么简单(我认为,接口可以使这项工作变得更加困难)。但是,这些错误可以通过安全转换来修复:

// Works fine :)
let testSeqWithCast = seq {
    yield A(0)
    yield B(1) :> A
    yield C(2) :> A
}

如果我不想使用强制转换怎么办?我尝试直接从“seq”指定序列类型,但事情似乎不起作用:

// Should work, I think...
let testGenSeq = seq<A> {
    yield A(0)
    yield B(1) // Error, expected type: A
    yield C(2)
}

所以,我的问题是:有没有办法避免强制转换?如果不是,是否有原因导致即使指定类型也无法使代码正常工作?

我尝试通过以下链接进行挖掘:

http://msdn.microsoft.com/en-us/library/dd233209.aspx http://msdn.microsoft.com/en-us/library/dd233209.aspx http://lorgonblog.wordpress.com/2009/10/25/overview-of-type-in​​ference-in-f/ http://lorgonblog.wordpress.com/2009/10/25/overview-of-type-inference-in-f/

但我发现没有什么有用的...

预先感谢您提供的任何类型的答案:)


这是一个很好的问题,答案可能比您迄今为止得到的答复所显示的更复杂。例如,这确实有效:

let l : A list = [A(0); B(1); C(2)]

但这段看似相似的代码却并非如此:

let s : A seq = seq { yield A(0); yield B(1); yield C(2) }

原因其实很微妙。第二种情况脱糖为基本上更复杂的版本:

let s : A seq = 
    Seq.append (Seq.singleton (A(0))) 
               (Seq.append (Seq.singleton (B(1))) 
                           (Seq.singleton (C(2)))))

所以有什么问题?归根结底,问题在于Seq.singleton具有泛型类型'x -> 'x seq,但我们想通过B并取回A seq在第二次调用中(通过隐式向上转换实例)。 F#will隐式向上转换函数输入 1concrete键入一个concrete基本类型(例如,如果Seq.singleton有签名A -> A seq we could pass a B!)。不幸的是,泛型函数不会发生这种情况(泛型、继承和类型推断不能很好地协同工作)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

F# 中序列表达式的类型推断 的相关文章

随机推荐

  • Openshift 端口转发

    已经有很多关于它的话题了 但我被困住了 我配置ssh成功了 现在我想配置端口转发以与 TOAD 连接 我用的是这个 https blog openshift com getting started with port forwarding
  • 如何最好地继承原生 JavaScript 对象? (特别是字符串)

    我是一个长期浏览者 但还是第一次参与者 如果我缺少任何礼仪细节 请告诉我 另外 我到处搜索 包括这个网站 但我还没有找到关于我想要做什么的清晰而简洁的解释 如果我错过了 请为我指出正确的方向 好吧 我想扩展一些原生 JavaScript 对
  • 重大地点变更如何运作?

    谁能确认重大位置变更是如何运作的 当用户移动时 iPhone 的蜂窝接收器从一个蜂窝塔切换到另一个蜂窝塔时 会计算移动吗 移动是通过在 可见 蜂窝塔之间进行三角测量来计算的 以最好地计算用户的位置 移动是根据与desiredAccuracy
  • 从 lsof(Linux 命令行)中提取字段/属性

    随着最近迁移到 Flash 10 或者可能是发行版选择 我和许多其他人不再能够从 tmp 复制 Flash 视频 不过 我在以下方面找到了解决方法 首先 执行 lsof grep Flash 它应该返回如下输出 plugin co 8935
  • 为什么 IE9 放弃了对文件 API 和文件输入的多重属性的支持?

    为什么 IE9 放弃了对文件 API 和文件输入的多重属性的支持 Chrome Firefox 和 Safari 支持这些功能 但 IE9 和 Opera 由于某种未知的原因未能支持这些 对于 IE9 我们似乎仍然坚持使用 Flash 来支
  • F# 实例语法

    F 中的成员声明使用什么指示符 我更喜欢 member a MethodName this是许多字母和x否则使用 我几乎总是使用x作为名字this实例 除了它比其他选项短这一事实之外 这背后没有任何逻辑 我见过的选项是 member x F
  • 在Android中获取html的textarea的值

    我有一个网页加载于WebView 有四个TextAreas存在于网页我在页面加载后填写WebView当我填充它们时 我想得到的值TextAreas点击Next Button在我的 Android 中 下一个按钮在 Android 中而不是在
  • 我可以从 Grails 插件外部控制插件加载顺序吗?

    我想从 Grails 插件外部控制插件加载顺序 在插件中 您可以使用 dependentOn loadAfter 或 loadBefore 控制加载顺序 http grails org doc latest guide plugins ht
  • 在哪里定义模板类的 static const 成员变量

    根据这个问题 https stackoverflow com q 2605520 368599 answer https stackoverflow com questions 2605520 c where to initialize s
  • 将字符串的第一个字节加一

    我有一个main程序 int main char str hello printf s n str Shift first byte 1 to get iello Have tried str 0 gt gt 8 printf s n st
  • 如果我执行 Object a=b 然后 b.change() 也会改变吗?

    如果我有 public class Bike private int speed public void setSpeed int speed this speed speed public int getSpeed return spee
  • newInstance() 与 new

    调用 newInstance 是否会受到惩罚 或者底层的机制是否相同 newInstance 相对于 new 关键字 有多少开销 如果有的话 忽视了 newInstance 暗示使用反射的事实 在现实世界的测试中 通过传递 10 个参数的
  • 如何防止 TabControl 中 UserControl 的延迟加载?

    我刚刚发现 TabControl 中的 UserControls 在选择父 TabPage 之前不会加载 有没有办法防止这种延迟加载 我需要在主窗体加载时初始化用户控件 The TabControl并没有特别对待它的控件 实际上在任何情况下
  • VS2012:调试器启动时 ntdll.dll 中的断点,没有更多信息

    有时 当我使用 VS2012 在调试模式下启动 调试应用程序时 我会看到一个对话框 已触发断点 它不包含其他信息 所以我点击了 break 来看看发生了什么 哦 但是后来我得到 wntdll pdb not returned 并且没有关于该
  • 如何使用 Hive 获取以分钟为单位的日期差异

    下面的查询是我的 sql server 查询 我希望它将其转换为 hive 查询 select DATEDIFF minute 19000101 2013 01 01 10 10 10 你可以使用unix timestamp https c
  • Webpack 4 和 Uglify 插件(TypeError:无法读取未定义的属性“长度”)

    我在 Linux 机器上使用 Webpack 4 时遇到问题 构建在开发模式下运行良好 但在生产模式下失败 它似乎也可以在 Windows 机器上运行 我确实尝试将 webpack 降级到旧版本 但什么也没做 节点js v10 2 1 Ty
  • 如何将第一个 POSIX `[:cntrl:]` 字符与旧版 BSD `awk` 匹配?

    我想将输入字符串的第一个 ASCII 控制字符与awk但我偶然发现了旧版 BSD 上的一个错误 bin bash printf a b c n awk match 0 cntrl print RSTART 1 预期输出为 3 代码可能有什么
  • JAVA:如何使用公共证书和私钥建立SSL连接

    我希望能就我今天遇到的问题获得一些帮助 我正在尝试使用我们客户之一的服务器对我的客户端进行身份验证 我可以通过发出以下命令来执行此操作 卷曲 v k H 内容类型 application json key privkey pem cert
  • 在 iOS 中使用 LDAP 进行身份验证

    我一直在寻找有关在 iOS 设备上使用 LDAP 的教程 这可能吗 我还没有看到任何关于它的文章或教程 是否还有其他方法可以针对我的 Active Directory 进行身份验证 有人能指出我正确的方向吗 我的 iOS Ports 项目中
  • F# 中序列表达式的类型推断

    我想我不太明白 F 如何推断序列表达式中的类型 以及为什么即使我直接从 seq 指定元素的类型也无法正确识别类型 在以下 F 代码中 我们有一个基类 A 和两个派生类 B 和 C type A x member a X x type B x