繁体   English   中英

如何在`for ... in`中对union构造函数进行模式匹配

[英]How to pattern match on union constructors in `for .. in`

在Haskell中,如果我有一个联合类型值的列表,如下所示:

example :: [Either Int Char]
example = [Left 3, Right 'b', Left 6, Left 9, Right 'c']

我可以使用一些“技巧”来提取匹配某些特定模式的所有结果:

lefts :: [Int]
lefts = [l | Left l <- example]

但是,如果我尝试将其转换为F#,我会收到错误:

let lefts = [for Choice1Of2 l in example -> l]
                 ~~~~~~~~~~~~
Incomplete pattern matches on this expression. (...)

这很有意义(甚至可能比默默地忽略像Haskell那样的Right值更好!)但是在F#中,是否有一些方便的方法来提取(和匹配)匹配列表中某个模式的所有值/顺序

在F#中如果你不匹配所有情况,你会在所有情况下得到警告。

所以你可以在表达式中写出两个案例的匹配,但是对于你的例子而不是理解我会使用函数List.choose

let example = [Choice2Of2 3; Choice1Of2 'b'; Choice2Of2 6; Choice2Of2 9; Choice1Of2 'c']
List.choose (function (Choice1Of2 x) -> Some x | _ -> None) example
// val it : char list = ['b'; 'c']

这个功能对于这些情况很方便。

我认为使用F#list表达式最接近的事情是这样的:

let lefts example = 
  [ for e in example do
      match e with Choice1Of2 l -> yield l | _ -> () ]

如果我正确理解Haskell代码,那么|之后的部分 不仅用作提取器,还用作过滤器 - 隐含地跳过与模式不匹配的所有事物。

F#在列表表达式中没有相同的概念,因此您必须更加详细。 在这里,我们只使用for迭代所有项目,然后我们显式使用yield为源列表中的每个Choice1Of2生成一个新值(我们只是跳过其他任何内容)。

根据你正在做的事情,使用List.choose (如Gustavo的回答中提到的)可能会更容易。 但上面可能是最接近Haskell的理解语法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM