元组列表中的模式匹配和列表理解

时间:2011-06-06 12:17:05

标签: list haskell pattern-matching list-comprehension

type a = [(Int,Int,Int,Int)]

fun:: a -> Int
func [a,b,c,d] = ?

我有一个像这样的元组列表我需要的是应用list comprehensionspattern matching ..示例采用总和或过滤仅划分2个数字 ... i只想开始如何访问这个元组列表

的值和/或列表理解

2 个答案:

答案 0 :(得分:8)

总结a,请使用以下内容:

type A = [(Int, Int, Int, Int)]

func :: A -> Int
func tuples = sum [a | (a, b, c, d) <- tuples]

另请注意,类型别名必须以大写字母开头。小写字母用于变量类型

答案 1 :(得分:3)

hammar的答案涵盖列表推导,使用模式匹配的递归函数的基本模式是:

f [] = ..
f ((a,b,c,d):xs) = ..

因此,您需要为不包含4元组的列表指定基本案例,并为列表包含4元组(a,b,c,d)后跟a(可能为空,可能非空)的递归情况)4元组列表xs。第二行上的模式是嵌套模式:它首先将列表与(x:xs)之类的模式匹配,即元素x后面是列表xs的其余部分;然后它将x与4元组结构相匹配。

下面,我将给出一些基本的例子。请注意,您也可以使用标准的高阶函数(例如filtermap)来编写此函数,并且我谨慎地不提及@之类的内容 - 模式和严格性。我不建议这样做,但它只是给你一个想法!

当你想要对元组的第一部分求和时,你可以这样做:

sum4 :: [(Int,Int,Int,Int)] -> Int
sum4 [] = 0
sum4 ((a,b,c,d):xs) = a + sum4 xs

如果您要过滤掉所有abcd均为偶数的元组:

filter4allEven :: [(Int,Int,Int,Int)] -> [(Int,Int,Int,Int)]
filter4allEven [] = []
filter4allEven ((a,b,c,d):xs) 
    | all even [a,b,c,d] = (a,b,c,d) : filter4AllEven xs
    | otherwise = filter4AllEven xs

(如果使用all会让您感到困惑,请阅读even a && even b && even c && even d

最后,这是一个函数,它返回所有偶数元组件(元组本身不能均匀!)的顺序与它们在参数列表中出现的顺序相同:

evenTupleComponents :: [(Int,Int,Int,Int)] -> [Int]
evenTupleComponents [] = []
evenTupleComponents ((a,b,c,d):xs) = [x | x <- [a,b,c,d], even x] ++ evenTupleComponents

一旦你做了这样的几个练习,你就会明白为什么使用标准函数是一个好主意,因为它们都遵循类似的模式,比如将函数分别应用于每个元组,包括或排除元组时一些属性,或者更一般地说,给出空列表的基值和递归情况的组合函数。例如,我会将evenTupleComponents写为evenTupleComponents = filter even . concatMap (\(a,b,c,d) -> [a,b,c,d]),但这是一个不同的故事:)