我正在寻找一个函数,它可以给我一个字母的所有匹配数字,例如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]
我得到一个解析器错误。
我正在寻找一个函数,它可以给我一个字母的所有匹配数字,例如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]
我得到一个解析器错误。
您不需要模式匹配或列表推导,因为我会说使用过滤器和映射更容易:
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)
作为参数,因为x <- xs
循环遍历所有xs
.
或者,您可以更简单地做到这一点
giveNumber letter xs = [y | (x, y) <- xs, x == letter]
在这三个选项中,这个可能是最易读和最容易理解的,但我最喜欢第一个,因为它全部来自组合高阶函数并且可以 eta 简化为
giveNumber x = map snd . filter ((== x) . fst))
使ys
参数隐式。
您可能还对lookup
内置的功能感兴趣:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
但这仅查找单个元素,并有可能失败。
你有两个小错误:
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]