F#:贬低一个受歧视的联盟

时间:2014-11-24 18:02:42

标签: casting f# downcast discriminated-union

我有一个有区别的联合类型:

type F =
| A of int
| B of float

假设我有一个已被过滤的F列表,只能生成A类型的对象:

let listOfAs=list.filter (fun f -> match f with | A(f') -> true | _ -> false)

如何处理结果列表F而不需要在我的代码中到处都是模式匹配?编译器不喜欢直接强制转换,例如

list.map (fun f -> int f) listOfAs

1 个答案:

答案 0 :(得分:9)

你不能真正建立有区别的联合值 - F的类型与类型int不同(它不像C联合,它们具有相同的二进制表示)。

因此,最简单的解决方案是编写一个带list<F>并返回list<int>的函数,该函数仅包含int案例中包含的A值。

为此,您可以使用List.choose(而不是List.filter)。这允许您指定一个投影,您可以在其中返回None(意味着跳过值)或Some v(意味着返回值v作为结果列表的一部分):

let listOfAs = List.choose (fun f -> 
  match f with 
  | A(f') -> Some f'
  | _ -> None)