模式匹配可以用于列表成员吗?
Can Pattern Matching be used for list membership?
我知道我可以使用守卫来检查某个值是否出现在列表中,但我想知道 单独的模式匹配 是否也可以用于此。
-- Using guards
f :: [Int] -> Int
f xs
| 42 `elem` xs = 42
| otherwise = 0
-- Using pattern matching?
g :: [Int] -> Int
g (_:)*42:_ = 42 -- i.e. zero or more elements: we discard until 42, followed by whatever.
g _ = 0
简答:否
长答案:
模式递归定义如下:
pattern := variable
| constant
| C p1 p2... where C is a constructor and p1 p2... are patterns
| variable@pattern
Can Pattern Matching be used for list membership?
仅通过递归地应用模式,例如
elem :: Eq a => a -> [a] -> Bool
elem x [] = False
elem x (y:ys) = x == y || elem x ys
所以 none 模式 []
和 y:ys
自己检查列表成员。
但是与递归相结合,它们是有帮助的。
"Zero or more elements we discard until 42, followed by whatever."
没有。
此模式将仅匹配以 42
作为第二个元素的列表。 :
是列表构造函数,composes\decomposes 以独特的方式列出的东西,而不是连接,连接是 "to complex" 用于模式匹配。
是的。仅使用文字 Int
值;递归地。
-- Using pattern matching alone
g :: [Int] -> Int
g (42:_) = 42
g [] = 0
g (_:r) = g r
测试:
> g [1..50]
42
> g [1]
0
虽然模式中没有类似正则表达式的结构。我希望我们可以写类似
的东西
foo [...xs, 42, ...ys] = xs ++ ys
foo _ = []
但我们不能。
更新:根据@chi in the 的建议;使用 查看模式;
{-# LANGUAGE ViewPatterns #-}
g2 (break (== 42) -> (_,[])) = 0 -- 0, if not found
g2 _ = 42 -- 42, otherwise
我不确定它是否算作 "patterns alone",因为它使用 "regular" 标准函数 break
。优点是,它不再只是文字。
你可以,在某种程度上,但它需要启用 GHC 扩展。
{-# LANGUAGE ViewPatterns -#}
g :: [Int] -> Int
g ((42 `elem`) -> True) = 42
g _ = 0
如果 f x
匹配 v
.
,则 f -> v
形式的模式匹配参数 x
我知道我可以使用守卫来检查某个值是否出现在列表中,但我想知道 单独的模式匹配 是否也可以用于此。
-- Using guards
f :: [Int] -> Int
f xs
| 42 `elem` xs = 42
| otherwise = 0
-- Using pattern matching?
g :: [Int] -> Int
g (_:)*42:_ = 42 -- i.e. zero or more elements: we discard until 42, followed by whatever.
g _ = 0
简答:否
长答案:
模式递归定义如下:
pattern := variable
| constant
| C p1 p2... where C is a constructor and p1 p2... are patterns
| variable@pattern
Can Pattern Matching be used for list membership?
仅通过递归地应用模式,例如
elem :: Eq a => a -> [a] -> Bool
elem x [] = False
elem x (y:ys) = x == y || elem x ys
所以 none 模式 []
和 y:ys
自己检查列表成员。
但是与递归相结合,它们是有帮助的。
"Zero or more elements we discard until 42, followed by whatever."
没有。
此模式将仅匹配以 42
作为第二个元素的列表。 :
是列表构造函数,composes\decomposes 以独特的方式列出的东西,而不是连接,连接是 "to complex" 用于模式匹配。
是的。仅使用文字 Int
值;递归地。
-- Using pattern matching alone
g :: [Int] -> Int
g (42:_) = 42
g [] = 0
g (_:r) = g r
测试:
> g [1..50]
42
> g [1]
0
虽然模式中没有类似正则表达式的结构。我希望我们可以写类似
的东西foo [...xs, 42, ...ys] = xs ++ ys
foo _ = []
但我们不能。
更新:根据@chi in the
{-# LANGUAGE ViewPatterns #-}
g2 (break (== 42) -> (_,[])) = 0 -- 0, if not found
g2 _ = 42 -- 42, otherwise
我不确定它是否算作 "patterns alone",因为它使用 "regular" 标准函数 break
。优点是,它不再只是文字。
你可以,在某种程度上,但它需要启用 GHC 扩展。
{-# LANGUAGE ViewPatterns -#}
g :: [Int] -> Int
g ((42 `elem`) -> True) = 42
g _ = 0
如果 f x
匹配 v
.
f -> v
形式的模式匹配参数 x