You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Haskell中`[_]`模式的含义是什么?其与`(x:xs)`模式匹配是否等价?

Haskell中[_]模式的含义及与(x:xs)的区别

嘿,咱们来把这个问题掰扯清楚——这两个模式在Haskell里的差异其实挺关键的,很容易搞混!

先说说[_]模式到底是什么

[_]是一个专门匹配恰好包含一个元素的列表的模式。这里的下划线_是通配符,表示我们完全不关心这个唯一元素的具体值,只在乎列表的长度是1。

举几个例子:

  • [42]["foo"][True]都会匹配这个模式
  • 空列表[]、双元素列表[1,2]、更长的列表[a,b,c]不会匹配它

本质上,[_](_:[])的语法糖——因为Haskell里所有非空列表都是用cons运算符:构建的,x:xsx是首元素,xs是剩余元素组成的子列表。当xs是空列表[]时,就刚好是单元素列表,所以[_](_:[])是完全等价的。

再对比function [_] = []function (x:xs) = []

这两个模式匹配完全不一样,核心差异在于匹配的列表范围:

  • function [_] = []:只有当输入是单元素列表时,才会触发这个分支,返回空列表。如果输入是空列表或者多元素列表,没有其他模式分支的话,程序会抛出非穷尽模式的错误。
  • function (x:xs) = []:只要输入是非空列表(不管长度是1还是更长),都会触发这个分支,返回空列表。只有输入是空列表时,才会不匹配这个分支。

用实际调用的例子看更直观:

  1. 调用function [5]:两个定义都会返回[],因为[5]同时符合两个模式
  2. 调用function [1,2,3]:第一个定义不匹配(不是单元素列表),会报错;第二个定义匹配,返回[]
  3. 调用function []:两个定义都不匹配,都会报错(除非你加了function [] = ...的分支)

总结一下

  • [_]模式:精准匹配长度为1的列表,忽略唯一元素的值
  • (x:xs)模式:匹配所有非空列表,可以捕获首元素和剩余子列表

内容的提问来源于stack exchange,提问作者Connor

火山引擎 最新活动