Haskell中`[_]`模式的含义是什么?其与`(x:xs)`模式匹配是否等价?
Haskell中
[_]模式的含义及与(x:xs)的区别 嘿,咱们来把这个问题掰扯清楚——这两个模式在Haskell里的差异其实挺关键的,很容易搞混!
先说说[_]模式到底是什么
[_]是一个专门匹配恰好包含一个元素的列表的模式。这里的下划线_是通配符,表示我们完全不关心这个唯一元素的具体值,只在乎列表的长度是1。
举几个例子:
[42]、["foo"]、[True]都会匹配这个模式- 空列表
[]、双元素列表[1,2]、更长的列表[a,b,c]都不会匹配它
本质上,[_]是(_:[])的语法糖——因为Haskell里所有非空列表都是用cons运算符:构建的,x:xs里x是首元素,xs是剩余元素组成的子列表。当xs是空列表[]时,就刚好是单元素列表,所以[_]和(_:[])是完全等价的。
再对比function [_] = []和function (x:xs) = []
这两个模式匹配完全不一样,核心差异在于匹配的列表范围:
function [_] = []:只有当输入是单元素列表时,才会触发这个分支,返回空列表。如果输入是空列表或者多元素列表,没有其他模式分支的话,程序会抛出非穷尽模式的错误。function (x:xs) = []:只要输入是非空列表(不管长度是1还是更长),都会触发这个分支,返回空列表。只有输入是空列表时,才会不匹配这个分支。
用实际调用的例子看更直观:
- 调用
function [5]:两个定义都会返回[],因为[5]同时符合两个模式 - 调用
function [1,2,3]:第一个定义不匹配(不是单元素列表),会报错;第二个定义匹配,返回[] - 调用
function []:两个定义都不匹配,都会报错(除非你加了function [] = ...的分支)
总结一下
[_]模式:精准匹配长度为1的列表,忽略唯一元素的值(x:xs)模式:匹配所有非空列表,可以捕获首元素和剩余子列表
内容的提问来源于stack exchange,提问作者Connor




