我喜欢
type A =
| X of string
| Y of int
我有一系列X类型,[X "foo"; X "boo"; X "moo"]
是否有一个快捷方式可以将地图转换为["foo"; "boo"; "moo"]
而不进行匹配?
谢谢!
答案 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
获取X
或Y
的列表,但不是两者。
[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
但请注意,如果给出错误案例的值,他们会提出异常。