msi*_*erc 1 haskell list-comprehension pattern-matching
我正在寻找一个函数,例如,它给了我所有匹配的字母数字 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]
Run Code Online (Sandbox Code Playgroud)
我得到一个解析器错误...谢谢
您不需要模式匹配或列表推导,因为我会说使用过滤器和地图会更容易:
giveNumber :: (Eq a) => [(a, b)] -> [b]
giveNumber x ys = map snd $ filter ((== x) . fst) ys
Run Code Online (Sandbox Code Playgroud)
虽然您可以通过对代码进行一些小的调整来实现:
giveNumber letter xs = [snd x | x <- xs, fst x == letter]
Run Code Online (Sandbox Code Playgroud)
这可能对你更有意义,但要么在执行时间大致相同.你做错了的是你|
在理解中有第二个符号,你需要一个逗号,而你不需要将匹配模式(x:xs)
作为一个参数,因为x <- xs
循环遍及所有xs
.
或者,你可以更简单地做到这一点
giveNumber letter xs = [y | (x, y) <- xs, x == letter]
Run Code Online (Sandbox Code Playgroud)
在这三个选项中,这一个可能是最易读和最容易理解的,但我最喜欢第一个,因为它全部来自组成高阶函数,并且可以简化为
giveNumber x = map snd . filter ((== x) . fst))
Run Code Online (Sandbox Code Playgroud)
使ys
参数隐式.
您可能还对lookup
内置的函数感兴趣:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
Run Code Online (Sandbox Code Playgroud)
但这只会查找单个元素,可能会失败.
你有2个小错误:
1)你错过了昏迷 [("D", 5), ("A", 4) , ("D", 25)]
2)在列表理解中你使用了|
两次,而不是一次
giveNumber letter xs = [snd x | x <- xs , fst x == letter]
Run Code Online (Sandbox Code Playgroud)
你可以写一点更漂亮:
giveNumber letter xs = [y | (x,y) <- xs , x == letter]
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这个函数更通用String -> [(String, a)] -> [a]
:
giveNumber :: Eq a => a -> [(a, t)] -> [t]
Run Code Online (Sandbox Code Playgroud)