如何用Haskell模式匹配判断五元素列表前四个元素是否相同?
解决Haskell五元素列表前四个元素相同的模式匹配问题
首先,你第一次写的代码报错是因为Haskell默认不允许在模式里重复使用同一个变量名——这里的四个x会被当成四个独立的新变量,而非指代同一个值,所以编译器提示“x的冲突定义”。
要实现需求,有两种符合模式匹配思路的可行方式:
方式一:模式匹配+守卫(最简洁,无需启用扩展)
先通过模式匹配锁定五元素列表的结构,再用守卫验证前四个元素的值相等:
checkFour :: Eq a => [a] -> Int checkFour [w, x, y, z, _] | w == x && x == y && y == z = 0 checkFour _ = 1 -- 非五元素列表或前四个元素不同的情况
这里的模式[w, x, y, z, _]先匹配出五元素列表的前四个元素,再通过守卫完成相等性检查,完全贴合你“用模式匹配解决”的需求。
方式二:模式同义词(纯模式匹配语法,需启用扩展)
如果想完全用模式匹配的语法实现(不写守卫条件),可以启用Haskell的PatternSynonyms扩展,定义一个带约束的自定义模式:
{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ViewPatterns #-} -- 定义模式,匹配前四个元素相同的五元素列表 pattern FourSame a <- [a, a, a, a, _] where FourSame a = [a, a, a, a, undefined] -- 可选的构造器实现 checkFour :: Eq a => [a] -> Int checkFour (FourSame _) = 0 checkFour _ = 1
这个FourSame a模式会直接匹配前四个元素均为a的五元素列表,调用时直接用该模式匹配即可。
另外你用守卫时的错误,是因为_是模式匹配专属的通配符,不能用在列表字面量(表达式)里——列表元素必须是合法表达式,所以[head xs, head xs, head xs, head xs, _]这种写法不成立。
内容的提问来源于stack exchange,提问作者Alfy B
相关产品推荐
相关产品推荐

