从工会案例中获取价值

时间:2011-07-22 14:52:27

标签: f#

我喜欢

type A = 
   | X of string
   | Y of int

我有一系列X类型,[X "foo"; X "boo"; X "moo"] 是否有一个快捷方式可以将地图转换为["foo"; "boo"; "moo"]而不进行匹配?

谢谢!

5 个答案:

答案 0 :(得分:4)

我通常不会使用不能处理模式匹配的所有情况的解决方案(例如,当使用fun (X str) -> ...时。添加处理程序总是一个好主意,即使它只报告了更多信息错误(例如,该案例是意外的,因为它之前被过滤了。)

您可以使用function语法扩展kvb的解决方案(类似fun模式匹配):

List.map (function (X s) -> s | _ -> failwith "Unexpected case")

或者,如果您想忽略Y值(以便[X "a"; Y 1; X "b"]变为["a"; "b"]),您可以使用List.choose函数:

List.choose (function (X s) -> Some s | _ -> None)

要使用列表推导来编写此内容,您需要使用match使用完整的模式匹配,因此它比使用高阶函数要长一些。

答案 1 :(得分:3)

您可以使用:

List.map (fun (X s) -> s)

这确实在幕后执行匹配,但语法更好。你会得到一个警告,因为模式是部分的(也就是说,该函数显然无法处理Y _个实例)。

答案 2 :(得分:3)

只是为了笑容,你可以这样做:

let get<'T> = function
  | X s -> box s :?> 'T
  | Y i -> box i :?> 'T

获取XY的列表,但不是两者。

[X "foo"; X "boo"; X "moo"] |> List.map get<string>
[Y 0; Y 1; Y 2] |> List.map get<int>
[Y 0; X "boo"; Y 2] |> List.map get<int> //oh snap!

如果你对盒装值没问题,这适用于混合列表:

let get = function
  | X s -> box s
  | Y i -> box i

[Y 0; X "boo"; Y 2] |> List.map get //no problem

我假设你对非正统的解决方案感兴趣,因为你问的是如何避免模式匹配。 ; - )

Here是另一种通用的,但却是巴洛克式的解决方案。

答案 3 :(得分:2)

与@ kvb的解决方案类似,您可以使用不完整模式匹配的列表推导:

let xl = [X "foo"; X "boo"; X "moo"]
[for X s in xl -> s]

答案 4 :(得分:0)

你必须匹配。如果你这么做,定义函数getX和getY:

let getX (X v) = v

let getY (Y v) = v

但请注意,如果给出错误案例的值,他们会提出异常。