从自定义类型列表中过滤和提取的最佳方法?

pap*_*uck 3 haskell

我有一个表示命令行选项的数据类型:

data Flag = Verbose | Help | Buffer Int deriving (Show, Eq)

程序运行时,我得到一个列表Flag,与用户指定的选项相对应。例如,[Buffer 10, Verbose]

我的问题是,IntBufferin中提取值的最佳方法是什么[Flag]
该列表甚至可能没有Buffer
我要提出的只是某种复杂的遍历/折叠,它使用一条case语句Buffer从其他Flags中过滤掉。

Jos*_*ica 9

首先,请考虑以下功能:

buffers :: [Flag] -> [Int]
buffers xs = [b | Buffer b <- xs]
Run Code Online (Sandbox Code Playgroud)

Int从s内部返回仅s 的列表Buffer。对于[Verbose, Help],它将返回[]。对于[Buffer 10, Verbose],它将返回[10]。对于[Buffer 123, Buffer 456],它将返回[123, 456]

现在你有一个[Flag] -> [Int]。如果您还提出了一个[Int] -> Int,则可以对它们进行组合以获得[Flag] -> Int最初要求的,因此现在由您自己决定如何从该列表中获取一个整数。

listToMaybe是一种方法。Nothing如果列表为空,则返回,否则返回Just第一个元素。fromMaybe如果未提供默认缓冲区大小,则将其与之一起设置。

另外,您可以以某种方式组合多个缓冲区参数。max (0:buffers xs)将返回指定的最大缓冲区大小,如果没有,则返回0。(0:如果没有指定缓冲区大小,则程序将崩溃。)sum (buffers xs)将返回所有指定缓冲区大小的总和(如果没有,则自动返回0,因为空总和为0)。

  • @paperduck`x的大小:_-&gt; x; []-&gt; 0`会更惯用,因为(!!)函数不是合计的,因此,如果可能的话,最好避免使用它。 (4认同)
  • 通常,模式匹配要比`length`,`(!!)`,`head`或`tail`相匹配。所有这些都是通过模式匹配实现的,通常效率不如模式匹配低。 (2认同)