简体   繁体   English

如何引用封装在单个案例区分联合中的元组的第一个元素

[英]How to refer to the first element of a tuple encapsulated in a single-case discriminated union

Suppose you have a type like this: 假设你有这样的类型:

type Corner = Corner of int*int

and then some variable: 然后是一些变量:

let corner = Corner (1,1)

Is it possible to get the value of the first element of the tuple, something like: 是否有可能获得元组的第一个元素的值,如:

fst corner

Looks like some kind of unwrapping to int*int is necessary. 看起来有必要对int*int某种展开。

The answer provided by @Foole is good, but from the comment I get the impression that you don't like having to 'declare' the temporary variable first . 通过@Foole提供的答案是好的,但在征求意见,我得到的是你不喜欢到“声明”临时变量的印象first This can indeed feel cumbersome if all you want to do is to pull out the first value and then pipe it to another function. 如果你想要做的就是拉出第一个值然后将它传递给另一个函数,这确实会让人觉得麻烦。

There's no built-in facility that I'm aware of that lets you do this automatically. 没有我知道的内置工具可以自动执行此操作。 Consider that the Corner type given above is a degenerate case of a Discriminated Union (DU). 考虑到上面给出的Corner类型是Discriminated Union(DU)的简并情况。 Normally, DUs have more cases, and they are often heterogeneous in shape. 通常,DU具有更多的情况,并且它们通常在形状上是异质的。

There can be good reasons to have a single-case DU such as Corner , but then it often makes sense to also supply various 'helper' functions to make working with that type smoother. 有一个单一案例DU如Corner可以有充分的理由,但是通常也提供各种“帮助”功能以使这种类型的工作更顺畅。

In the case of the Corner type, you could define functions such as: 对于Corner类型,您可以定义以下函数:

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

let cornerY (Corner(_, y)) = y

Here, I've assumed that Corner models a coordinate, but if you'd like, you can also name the functions fst and snd . 在这里,我假设Corner模拟了一个坐标,但如果你愿意,你也可以命名函数fstsnd You can also put them in a dedicated module, if you rather prefer that. 如果您愿意,也可以将它们放在专用模块中。

This will enable you to extract and pipe a value from a Corner value without the hassle of a temporary variable: 这将使您能够从Corner值中提取和管道值,而无需临时变量的麻烦:

> corner |> cornerX |> ((*) 10) |> string;;
val it : string = "10"

where corner is defined as in the OP. 其中corner定义为OP。

I assume that was meant to be 我认为那是有意义的

type Corner = Corner of int*int

In which case, this will get the first value: 在这种情况下,这将获得第一个值:

let (Corner(first,_)) = corner

As already mentioned, it's not possible to get the first discriminated union case without naming it. 如前所述,在没有命名的情况下,不可能获得第一个受歧视的联合案例。 But here's quite a concise way to do it: 但这是一个非常简洁的方法:

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

This uses the function keyword, which creates a function with one parameter and jumps straight into a pattern match on that parameter. 这使用了function关键字,它创建了一个带有一个参数的函数,并直接跳转到该参数的模式匹配。 Since there's only one case to match on it fits neatly into one line. 由于只有一种情况可以匹配,因此它可以整齐地放入一条线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM