我对Haskell很新,我有一个问题 . 我有一个模块定义为:
inc :: Int->[Int]->[Int]
它应该做的是在第二个参数中返回第一个参数的所有出现 . 因此 1 [1,1,3]
的输出将返回 [1,1]
.
这就是我所拥有的:
inc :: Int->[Int]->[Int]
inc x [y] = if [x] == [y] then [x] else []
因为我在挣扎,所以我只是想知道它是否适用于一个数字而且确实如此 . 例如: 1 [1]
返回 [1]
. 但是,当我尝试使用多个值,如 1 [1,1]
时,我收到错误:
函数inc中的非穷举模式
我怎样才能调整我的程序,所以它能够处理多个值而不是一个值?
4 回答
当您想要检查某种类型的值时,您需要知道该类型的可能“形状”(即数据构造函数)是什么 .
对于列表,值具有以下两种形式之一:
空:
[]
非空:
h : t
(其中h
是列表的头部(第一个元素),t
是尾部(另一个列表))当您编写类似
[1, 2, 3]
的内容时,它实际上意味着1 : (2 : (3 : []))
(一个列表,其头部是1
,其尾部是另一个列表,其头部是2
,其尾部是另一个列表,其头部是3
,其尾部是[]
) .对于消耗列表的函数,这通常意味着您需要提供两个方程式:
处理空列表和
处理非空列表(
y
将是列表的第一个元素,ys
是剩余值) .您的实现不完整,它表示您只支持单个元素的列表 . 您需要扩展您的实现以涵盖所有可能性 . 使用递归迭代所有元素 . 可能的实现可能是:
列表值可以是以下任何一种形式
[]
[y1]
,即y1:[]
[y1,y2]
,即y1:y2:[]
[y1,y2,y3]
,即y1:y2:y3:[]
......
无限列表
y1:y2:y3:...
(迂腐地说,我们也有以底部结尾的列表,但我会忽略那些)
一个定义的等式
只考虑具有单个元素(
y
)的[y1]
形式的列表 . 所有其他情况都不匹配 .如果
y
是一个泛型列表参数,而不是单个元素,我们必须使用如我们所见,list参数不需要特殊语法 .
要检测非穷举错误,强烈建议在编译期间打开警告 . 如果我们这样做,GHC会报告我们错过了案例
[]
和_:_:_
,后者是一个至少包含两个元素的列表 .在Haskell中,尽可能避免显式递归,并通过使用函数来消除一些详尽的模式匹配 . 特别针对这种情况,您可以使用
filter
. 阅读其文档here使用此功能,您的程序可以写成:
或点自由风格: