首页 文章

非详尽的模式

提问于
浏览
1

我对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 回答

  • 0

    当您想要检查某种类型的值时,您需要知道该类型的可能“形状”(即数据构造函数)是什么 .

    对于列表,值具有以下两种形式之一:

    • 空: []

    • 非空: h : t (其中 h 是列表的头部(第一个元素), t 是尾部(另一个列表))

    当您编写类似 [1, 2, 3] 的内容时,它实际上意味着 1 : (2 : (3 : [])) (一个列表,其头部是 1 ,其尾部是另一个列表,其头部是 2 ,其尾部是另一个列表,其头部是 3 ,其尾部是 [] ) .

    对于消耗列表的函数,这通常意味着您需要提供两个方程式:

    inc x [] = ...
    

    处理空列表和

    inc x (y : ys) = ...
    

    处理非空列表( y 将是列表的第一个元素, ys 是剩余值) .

  • 1

    您的实现不完整,它表示您只支持单个元素的列表 . 您需要扩展您的实现以涵盖所有可能性 . 使用递归迭代所有元素 . 可能的实现可能是:

    inc :: Int->[Int]->[Int]
    inc _ [] = []
    inc x (y:ys) = if x == y then x:inc x ys else inc x ys
    
  • 0

    列表值可以是以下任何一种形式

    • []

    • [y1] ,即 y1:[]

    • [y1,y2] ,即 y1:y2:[]

    • [y1,y2,y3] ,即 y1:y2:y3:[]

    • ......

    • 无限列表 y1:y2:y3:...

    (迂腐地说,我们也有以底部结尾的列表,但我会忽略那些)

    一个定义的等式

    f [y] = ...
    

    只考虑具有单个元素( y )的 [y1] 形式的列表 . 所有其他情况都不匹配 .

    如果 y 是一个泛型列表参数,而不是单个元素,我们必须使用

    f y = ...
    

    如我们所见,list参数不需要特殊语法 .

    要检测非穷举错误,强烈建议在编译期间打开警告 . 如果我们这样做,GHC会报告我们错过了案例 []_:_:_ ,后者是一个至少包含两个元素的列表 .

  • 0

    在Haskell中,尽可能避免显式递归,并通过使用函数来消除一些详尽的模式匹配 . 特别针对这种情况,您可以使用 filter . 阅读其文档here

    使用此功能,您的程序可以写成:

    inc :: Int-> [Int] -> [Int]
    inc x ys = filter (==x) ys
    

    或点自由风格:

    inc x = filter (==x)
    

相关问题