List Haskell-函数中的非穷举模式
下面函数的要点是接收一个列表,并将该列表拆分为两个列表的元组。第一个列表将维护偶数索引项,第二个列表将维护奇数索引项。“Pos”是当前所在的位置。(函数调用时正在传入0)。传入的列表的初始元组是([],[]) 哈斯克尔正在报道List Haskell-函数中的非穷举模式,list,haskell,tuples,List,Haskell,Tuples,下面函数的要点是接收一个列表,并将该列表拆分为两个列表的元组。第一个列表将维护偶数索引项,第二个列表将维护奇数索引项。“Pos”是当前所在的位置。(函数调用时正在传入0)。传入的列表的初始元组是([],[]) 哈斯克尔正在报道 *** Exception: split.hs:(113,1)-(116,73): Non-exhaustive patterns in function split 我理解,它认为我没有涵盖应涵盖的“某些案例”,但我觉得我涵盖了所有案例 如果列表为空->返回传入的列表
*** Exception: split.hs:(113,1)-(116,73): Non-exhaustive patterns in function split
我理解,它认为我没有涵盖应涵盖的“某些案例”,但我觉得我涵盖了所有案例
如果列表为空->返回传入的列表元组
否则->将x固定到一个列表上,并在xs上递归
在我看来,这个函数是严格递减的,直到xs变成[],在这种情况下它停止
我遗漏了什么吗?当第一个列表为非空,但元组参数中的一个(或两个)列表为空时,没有匹配项,例如
split [1] ([], [])
但是,您的第二个子句似乎并不要求元组中的任何一个列表都是非空的,因此您可以将其更改为:
split (x:xs) (ys,zs) pos
| pos `mod` 2 == 0 = doSplit xs (ys ++ [x], zs) (pos + 1)
| otherwise = doSplit xs (ys, zs ++ [x]) (pos + 1)
当第一个列表为非空,但tuple参数中的一个(或两个)列表为空时,不存在匹配,例如
split [1] ([], [])
但是,您的第二个子句似乎并不要求元组中的任何一个列表都是非空的,因此您可以将其更改为:
split (x:xs) (ys,zs) pos
| pos `mod` 2 == 0 = doSplit xs (ys ++ [x], zs) (pos + 1)
| otherwise = doSplit xs (ys, zs ++ [x]) (pos + 1)
如果列表不是空的,但元组包含空列表,会发生什么情况?您可以使用
偶数pos
而不是pos`mod`2==0
。(我意识到这并不能解决您的问题,但Zeta解决了)这不重要,函数不是在元组上递归的。[]+[x]不是有效的语句吗?事实上,几乎总是这样,因为传入的元组实际上是空的。是否有一种方法可以指定我希望它在这两种情况下都执行递归?如果列表不是空的,但元组包含空列表,会发生什么情况?您可以使用偶数pos
而不是pos`mod`2==0
。(我意识到这并不能解决您的问题,但Zeta解决了)这不重要,函数不是在元组上递归的。[]+[x]不是有效的语句吗?事实上,几乎总是这样,因为传入的元组实际上是空的。有没有一种方法可以让我指定我希望它在这两种情况下都执行递归?谢谢!我想我没有意识到(y:ys)推断了一个cons对,而不仅仅是“which's there”@Aserian:
实际上是列表的两个构造函数之一,另一个是[]
。您可以并且应该像对待任何其他模式匹配的构造函数一样对待它。@Aserian匹配任何列表的模式是ys
。类型表示它是一个列表;您不需要在变量中使用任何特殊符号来表示它是一个列表y:ys
只能是“某物被消耗到某物上”;无论您为y
和ys
选择什么值,该表达式都不可能最终等于[]
。谢谢!我想我没有意识到(y:ys)推断了一个cons对,而不仅仅是“which's there”@Aserian:
实际上是列表的两个构造函数之一,另一个是[]
。您可以并且应该像对待任何其他模式匹配的构造函数一样对待它。@Aserian匹配任何列表的模式是ys
。类型表示它是一个列表;您不需要在变量中使用任何特殊符号来表示它是一个列表y:ys
只能是“某物被消耗到某物上”;无论为y
和ys
选择什么值,该表达式都不可能最终等于[]
。