Haskell列表理解和模式匹配

时间:2013-10-18 14:13:34

标签: haskell pattern-matching list-comprehension

我正在寻找能给我所有匹配数字的函数,例如giveNumber "D" [("D", 5), ("A", 4) ("D", 25)] = [5,25]

giveNumber :: String -> [(String, a)] -> [a]
giveNumber letter (x:xs) = [snd x | x <- xs | fst x == letter]

我得到一个解析器错误... 感谢

2 个答案:

答案 0 :(得分:7)

您不需要模式匹配或列表推导,因为我会说使用过滤器和地图会更容易:

giveNumber :: (Eq a) => [(a, b)] -> [b]
giveNumber x ys = map snd $ filter ((== x) . fst) ys

虽然您可以对代码进行一些小的调整来实现:

giveNumber letter xs = [snd x | x <- xs, fst x == letter]

这可能对你更有意义,但要么在执行时间大致相同。你做错了的是你在理解中有一个第二个|符号,你需要一个逗号,而你不需要将匹配(x:xs)模式化为参数,因为{{1} }遍历所有x <- xs

或者,您可以更简单地将其作为

xs

在这三个选项中,这一个可能是最易读和最容易理解的,但我最喜欢第一个,因为它全部来自组成更高阶的函数,并且可以简化为

giveNumber letter xs = [y | (x, y) <- xs, x == letter]

隐含giveNumber x = map snd . filter ((== x) . fst)) 参数。

您可能还对内置的ys函数感兴趣:

lookup

但这只会查找单个元素,可能会失败。

答案 1 :(得分:6)

你有2个小错误:

1)你错过[("D", 5), ("A", 4) , ("D", 25)]

中的昏迷

2)在列表理解中,您使用|两次,而不是一次

giveNumber letter xs = [snd x | x <- xs , fst x == letter]

你可以写得更漂亮一点:

giveNumber letter xs = [y | (x,y) <- xs , x == letter]

顺便说一句,这个函数比String -> [(String, a)] -> [a]更通用:

giveNumber :: Eq a => a -> [(a, t)] -> [t]