【问题标题】:F#: downcast a discriminated unionF#:沮丧的歧视工会
【发布时间】:2015-01-22 13:03:18
【问题描述】:

我有一个可区分的联合类型:

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

【问题讨论】:

    标签: casting f# downcast discriminated-union


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 附带说明,通过将fun f -> 替换为function 关键字并删除match 行,可以将代码缩短一行。
    • 是的,可以 :-) 我通常在显示代码时不这样做,因为它需要同时解释两件事!
    猜你喜欢
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2012-12-17
    • 1970-01-01
    相关资源
    最近更新 更多