如何从Haskell中的列表中提取特定数据构造函数的术语

fin*_*son 13 haskell list pattern-matching

我在Haskell中遇到的一个常见问题是提取属于特定数据构造函数的列表中的所有项,我想知道是否有比我现在这样做更好的方法.

让我们说你得到了

data Foo = Bar | Goo
Run Code Online (Sandbox Code Playgroud)

, 列表

foos = [Bar, Goo, Bar, Bar, Goo]
Run Code Online (Sandbox Code Playgroud)

并希望从中提取所有Goos foos.目前我经常做类似的事情

goos = [Goo | Goo <- foos]
Run Code Online (Sandbox Code Playgroud)

一切都很好.问题是当Goo得到一堆字段时,我被迫写了类似的东西

goos = [Goo a b c d e f | Goo a b c d e f <- foos]
Run Code Online (Sandbox Code Playgroud)

这远非理想.你通常如何处理这个问题?

Don*_*art 23

似乎这个问题有两个部分:

  1. 有没有更简单的方法来进行模式匹配
  2. 列表理解在这里可以吗?

首先,有一个更好的方法来匹配你不关心字段:

goos = [ x | x@(Goo {}) <- foos]
Run Code Online (Sandbox Code Playgroud)

其次,使用列表推导是编写这些过滤器的完美结合方式.例如,在基础库中,catMaybes定义为:

catMaybes :: [Maybe a] -> [a]
catMaybes ls = [x | Just x <- ls]
Run Code Online (Sandbox Code Playgroud)

(来自基础库).所以成语很好.


ken*_*ytm 5

你可以用

[x | x@(Goo _ _ _ _ _ _) <- foos]
Run Code Online (Sandbox Code Playgroud)

你也可以定义一个

isGoo :: Foo -> Bool
isGoo (Goo _ _ _ _ _ _) = True
isGoo _ = False
Run Code Online (Sandbox Code Playgroud)

然后使用 filter

filter isGoo foos
Run Code Online (Sandbox Code Playgroud)

要么

[x | x <- foos, isGoo]
Run Code Online (Sandbox Code Playgroud)