F# 如何引用封装在单个区分大小写联合中的元组的第一个元素

F# 如何引用封装在单个区分大小写联合中的元组的第一个元素,f#,F#,假设您有这样一种类型: type Corner = Corner of int*int 然后是一些变量: let corner = Corner (1,1) > corner |> cornerX |> ((*) 10) |> string;; val it : string = "10" 是否可以获取元组的第一个元素的值,例如: fst corner 看起来有必要对int*int进行某种形式的展开。我想这是应该的 type Corner = Corner of

假设您有这样一种类型:

type Corner = Corner of int*int
然后是一些变量:

let corner = Corner (1,1)
> corner |> cornerX |> ((*) 10) |> string;;
val it : string = "10"
是否可以获取元组的第一个元素的值,例如:

fst corner

看起来有必要对
int*int
进行某种形式的展开。

我想这是应该的

type Corner = Corner of int*int
在这种情况下,将获得第一个值:

let (Corner(first,_)) = corner

@傻瓜提供的答案很好,但从评论中我得到的印象是,您不喜欢先“声明”临时变量
。如果您只想提取第一个值,然后通过管道将其传递给另一个函数,那么这确实会让您觉得很麻烦

据我所知,没有内置的设备可以让你自动完成这项工作。考虑上面给出的<代码>角>代码>是判别联盟(DU)的退化情况。通常情况下,DU有更多的病例,并且它们的形状通常是不均匀的

有很好的理由可以使用单个案例DU,例如
Corner
,但也可以提供各种“helper”函数,以使使用该类型的操作更加顺畅

对于
拐角
类型,您可以定义如下函数:

let cornerX (Corner(x, _)) = x

let cornerY (Corner(_, y)) = y
这里,我假设
Corner
为坐标建模,但如果您愿意,还可以命名函数
fst
snd
。如果您愿意,也可以将它们放在专用模块中

这将使您能够从
角点
值中提取并通过管道传输值,而无需临时变量:

let corner = Corner (1,1)
> corner |> cornerX |> ((*) 10) |> string;;
val it : string = "10"

如前所述,
在OP.

中定义,不命名就不可能得到第一个有区别的联合案例。但这里有一个非常简洁的方法:

Corner (1,1) |> function Corner (x,_) -> x

这将使用
function
关键字,该关键字创建一个具有一个参数的函数,并直接跳转到该参数的模式匹配中。因为只有一个大小写可以匹配,所以它可以整齐地放在一行中。

谢谢,我指的是类型,是:)但是,这个赋值意味着我需要一个临时变量来使用元组的成员(首先创建,然后引用)有可能为任何2元组/n元组单大小写区分并集获得通用版本吗?@mbx我不这么认为,因为实际发生的是大小写构造函数上的模式匹配。在模式匹配中,case构造函数的名称很重要:它实际上是一个函数。但是,请参阅@TheQuickBrownFox的答案,以获得一个简洁的内联替代方法,该方法不需要声明
let
-绑定函数。