在haskell中,有没有一种方法可以防止变量在递归内部发生变化?
我正在尝试定义 isInfixOf 函数,并且我找到了一个解决方案(希望它能正常工作:-)),
但由于 haskell 的递归性质,我编写了另一个(帮助)函数
几乎重复函数 isInfixOf 的代码。
这是代码:
myIsInfixOf :: (Eq a) =>; [一]-> [一]->布尔 myIsInfixOf [] [] = True myIsInfixOf [] 列表 = True myIsInfixOf 列表 [] = False myIsInfixOf 列表A 列表B | myIsInfixOf helpFunction listA listB == True = True |否则 = myIsInfixOf listA (tail listB)
helpFunction :: (Eq a) => [一]-> [一]->布尔 帮助函数 [] [] = True helpFunction [] 列表 = True 帮助函数列表 [] = False 帮助函数 (x:xs)(y:ys) | x == y = helpFunction xs ys |否则=假
我执行了帮助功能,因为我需要 myIsInfixOf 函数的第一个元素,不可触及。
如果我不创建这个 helpFunction,函数 myIsInfixOf 的第一个元素总是减少一个元素,这不好,因为我需要迭代函数 myIsInfixOf 的整个第二个元素,并检查与第一个元素是否相等它的元素。
在 helpFunction 的帮助下,列表中的第一个元素是不可触及的,只有第二个元素正在减少每次递归(这很好)。
那么,我可以将 myIsInfixOf 的第一个元素保存在某个地方,而不需要重新编码几乎所有内容吗?
谢谢。 :-)
i'm trying to define the isInfixOf function, and i came to a solution(hope it works good :-)),
but because of the recursion nature of haskell, i wrote another (help) function that
almost duplicate the code of the function isInfixOf.
this is the code:
myIsInfixOf :: (Eq a) => [a] -> [a] -> Bool
myIsInfixOf [] [] = True
myIsInfixOf [] list = True
myIsInfixOf list [] = False
myIsInfixOf listA listB | helpFunction listA listB == True = True
| otherwise = myIsInfixOf listA (tail listB)
helpFunction :: (Eq a) => [a] -> [a] -> Bool
helpFunction [] [] = True
helpFunction [] list = True
helpFunction list [] = False
helpFunction (x:xs)(y:ys) | x == y = helpFunction xs ys
| otherwise = False
i did the help function, because i need the first element of the myIsInfixOf Function, untouchable.
if i don't make this helpFunction, the first element of the function myIsInfixOf, always decrease by one element, which is not good, because i need to iterate throughout the whole second element of the function myIsInfixOf, and check for equality with the first element of it.
with the help of the helpFunction, my first element of the list is untouchable and just the second element is decreasing every recursion(which is good).
so, can i save somewhere, my first element of myIsInfixOf, without recode almost everything?
thanks. :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果你仔细观察的话,这两个函数其实并不那么相似。前三个“琐碎”案例是相同的,但最后一个案例在两个函数中执行不同的操作。您还可以在这两个函数中省略前两种情况,因为它们在相同的列表上检查相同的内容。所以
myIsInfixOf
也可以这样工作:这确实与
helpFunction
不同,并且不重复任何重要的代码。另外,您确实希望第二个函数独立于第一个函数工作,因为您希望检查
listB
中的每个位置,如果listA
的每个字符都与listB 中的字符匹配
。要在命令式程序中执行此操作,您需要嵌套循环,这里您需要一个嵌套递归,最好像您一样使用辅助函数来完成。问题不在于如果没有 helpFunction,listA
会以某种方式丢失,问题在于该算法需要helpFunction
独立于myIsInfixOf
运行列表>。如果您想通过使用标准库中的更多函数来避免手动实现
myIsInfixOf
的递归,您可以使用any
和tails
。对于helpFunction
可能显式递归是可行的方法,但您可以将最后一种情况简化为:The two functions aren't really all that similar, if you look at them. What is the same are the first three "trivial" cases, but the last case does different things in both functions. You could also leave out the first two cases in either of those functions since they check the same thing on the same lists. So
myIsInfixOf
also works like this:This really isn't the same as
helpFunction
, and doesn't repeat any nontrivial code.Also you really want the second function to work independently from the first, since you want to check for every position in
listB
if every character oflistA
matches those inlistB
. To do this in a imperative program you would need nested loops, here you need a nested recursion best done with a helper function like you did. The issue is not thatlistA
would somehow be lost without the helpFunction, the problem is that the algorithm requireshelpFunction
to run over the list independently ofmyIsInfixOf
.If you want to avoid manually implementing the recursion of
myIsInfixOf
by using more functions from the standard library you could useany
andtails
. ForhelpFunction
probably explicit recursion is the way to go, but you could simplify the whole last case to:请注意,1)在这两种情况下都不需要第一个子句,因为
[] list
也匹配[] []
并且返回相同的结果; 2)helpFunction listA listB == True
与helpFunction listA listB
相同。你在评论中说
事实上,事实并非如此。它检查第二个参数是否以第一个参数开始。这就是为什么你需要一个不同的函数。因此
helpFunction
的更好名称是myPrefixOf
。这应该可以帮助您从myIsInfixOf
的定义中消除另一个子句。Note that 1) you don't need the first clause in both cases, since
[] list
matches[] []
as well and you return the same result; 2)helpFunction listA listB == True
is the same ashelpFunction listA listB
.In the comment you said
Actually, it doesn't. It checks if the second argument starts with the first one. That's why you need a different function. So a better name for
helpFunction
ismyPrefixOf
. This should help you eliminate another clause from the definition ofmyIsInfixOf
.根据 Alexey Romanov 等人提出的一些建议,这将是我重写它的初步看法:
为了更直接地回答您的实际问题,请注意有关此版本的两件事:
In line with a few of the suggestions Alexey Romanov and sth made, this would be my initial take on rewriting it:
To more directly answer your actual question, note two things about this version:
我认为您在问题中混淆了“元素”和“论证”,至少在某些地方是这样。另外,你所说的“不可触碰”是什么意思?
回到你的问题:你可以使用所谓的 at-patterns 进行模式匹配并保留原始参数:
这使你可以将整个第一个参数称为 listA,将 listA 的第一个元素称为 x 和尾部作为 xs (与第二个参数相同)。这就是你的意思吗?
I think you're confusing 'element' and 'argument' in your question, at least in some places. Also, what do you mean by 'untouchable'?
To come back to your question: You can do a pattern match and keep the original argument around by using so-called at-patterns:
This lets you refer to the entire first argument as listA, the first element of listA as x and the tail as xs (and same for the second argument). Is that what you meant?