当我意识到我需要在某个地方提供额外的值时,我在编写 F# 时通常都会有一个“哦耶”的时刻。这通常可以通过向传递的元组添加另一个值来轻松完成。然而,这意味着各种地图/排序/收集/等。需要更新,特别是函数 fst/snd 仅适用于长度为 2 的元组。
这不是一个大问题,但在探索性开发过程中它已经足够烦人了,我想我会写一个助手来减轻烦恼:
let inline get2 (t:^a) = (^a : (member get_Item2 : unit -> string) (t, ()))
let inline get2a (t:^a) = (^a : (member Item2 : string) t)
但是,这两个版本都不起作用。首先,get2
,将无法编译,并显示“预期 1 个表达式,得到 2 个”。第二,get2a
,将编译,但随后不能在元组上使用:“类型 '(int * string)' 不支持任何名为 'get_Item2' 的运算符”。
有没有什么方法可以做到这一点而不涉及大量重载? 有噪音OverloadID
注释(F# 2.0 中不需要注释)
之所以ItemX
F# 元组上的静态约束不起作用是因为System.Tuple<_,...,_>
只是元组的编码形式,而不是编译器使用的静态表示形式。看6.3.2 元组表达式 http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc270597440在规范中。
但是,通过一些工作,您可以获得给定元组的运行时编码,如下所示:
open System
//like get2a but generic return type
let inline get2b (t:^a) = (^a : (member Item2 : 'b) t)
let x = (1,2)
let y = (1,2,3)
get2b (box x :?> Tuple<int,int>)
get2b (box y :?> Tuple<int,int,int>)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)