可以定义一个函数来判断一个元素是否是从给定的类型构造函数构造的吗?

Mic*_*rge 2 f# types discriminated-union

我在F#工作,并且有一个类型T,它是几个有区别的联合:

type T =
  | A of string * int
  | B of int
  | C
Run Code Online (Sandbox Code Playgroud)

如果我有一个T列表,我可能想要提取使用A构造的东西.这样的模式匹配很容易:

myList
|> List.filter (fun x -> match x with | A(_,_) -> true | _ -> false)
Run Code Online (Sandbox Code Playgroud)

嵌入式匹配有点冗长,并且在保持下划线数量与A的定义同步方面存在轻微的维护麻烦.我真的很喜欢这样的函数:

let constructedFrom (type constructor) (t : T) : bool = something

myList
|> List.filter (constructedFrom A)
Run Code Online (Sandbox Code Playgroud)

有没有办法定义这个'constructFrom'函数?

pad*_*pad 6

嵌入式匹配有点冗长,并且在保持下划线数量与A的定义同步时存在轻微的维护麻烦.

您可以使用function关键字保存一些按键.您还可以使用_忽略所有内容的模式(这并不意味着您必须绑定到单个值).

myList
|> List.filter (function A _  -> true | _ -> false)
Run Code Online (Sandbox Code Playgroud)

通常,如果您重复编写上述函数,则应定义一些活动模式,每种情况一个:

let (|ACase|_|) = function 
    | A _ as x -> Some x 
    | _ -> None

myList |> List.choose (|ACase|_|)
Run Code Online (Sandbox Code Playgroud)

有没有办法定义这个'constructFrom'函数?

没有惯用的方法.我认为主动模式可以在大多数时候解决问题.