Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell在循环中迭代并具有回溯能力_List_Haskell_Tuples - Fatal编程技术网

List Haskell在循环中迭代并具有回溯能力

List Haskell在循环中迭代并具有回溯能力,list,haskell,tuples,List,Haskell,Tuples,我目前正在学习Haskell,遇到了一个问题,我试图遍历一个列表,但我需要能够返回到列表的开头。例如,如果我的元组列表是: [1,5,4,3,5,6,1,7,7,9,3,11] 我需要从1到4到5。。。目前,我通过递归调用列表尾部的函数来实现这一点。这是应该的,但问题是: 我正在将这些数字与另一个元组列表进行匹配。举个例子,我的第二个列表是 [6,10] 所以1号或5号都不是6号或10号,4号或3号都不是6号或10号,而是5号或6号中的6号,所以我会把它加到前面。现在我需要从列表的最前面开始。问

我目前正在学习Haskell,遇到了一个问题,我试图遍历一个列表,但我需要能够返回到列表的开头。例如,如果我的元组列表是:

[1,5,4,3,5,6,1,7,7,9,3,11]

我需要从1到4到5。。。目前,我通过递归调用列表尾部的函数来实现这一点。这是应该的,但问题是:

我正在将这些数字与另一个元组列表进行匹配。举个例子,我的第二个列表是

[6,10]

所以1号或5号都不是6号或10号,4号或3号都不是6号或10号,而是5号或6号中的6号,所以我会把它加到前面。现在我需要从列表的最前面开始。问题是我迭代的方式,通过调用tail调用函数意味着我看不到1,5,4,3,这半个星期以来我一直在努力从概念上解决这个问题。我知道如何处理整个头列表:函数尾列表,但由于我返回的是匹配对的新列表,所以我无法完全实现这一点

不确定这是否有意义,但简而言之,在将5,6添加到列表后,我得到了[5,6,6,10]的结果,这很好,但当我现在想再次开始检查时,它以1,7开始,而不是现在匹配的1,5

<>我的代码现在在一个解决方案的中间,所以这将是一个巨大的混乱显示。另外,我真的只是想得到帮助,试图把我要做的事情概念化

编辑

好的,为了澄清一些困惑,假设我有两个列表:

清单1:[8,7,1,5,8,9,4,3,5,6,1,7,11,9] 清单2:[6,10,10,12]

我有一个函数,它接受两个列表并返回更新后的列表2。List1将其元组中的字符与list2元组前后的字符进行比较,我不想在两者之间插入字符,因为它们是链接的…,1010,。。。。所以从一开始,8,7与6或12都不匹配,所以我继续。现在,当我继续前进时,我将调用我的函数并将其传递给list1的尾部

例如: 主列表1列表2 |比较…=主尾部列表1添加列表列表2 . . . |否则=主尾部列表1列表2 为了节省空间,我并没有把所有的比较都写出来,但它们都很好,除了一个部分之外,清单上的内容应该是完整的。回到列表,我现在有1,5个不匹配的对象,所以我跳过尾部,得到8,9,再次没有任何结果,所以我前进,4,3个不匹配,所以我得到了5,6个匹配的对象,我可以翻转它并将其添加到前面,使其成为[5,6,6,10,10,12],现在我将从列表1中删除5,6,因为我已经将其添加到列表2中。现在的问题是,我将再次通过尾部,然后在1,7和11,9,这将结束程序,因为我们在列表的末尾

我期望的输出是[11,9,9,8,8,7,7,1,1,5,5,6,6,10,12],而不是[5,6,6,10,10,12]


再说一遍,代码并不能真正帮助我,我只是希望有人提供一种不同的方式来思考它。这是我第一次接触函数式语言,说我对某些部分感到困惑是轻描淡写的

既然您正在学习Haskell,我想您可能想自己解决这个问题,那么让我来告诉您如何解决一个更简单的变量。假设我们有一个单词列表,我们想要建立一个新的单词列表,其中,对于每个相邻的单词对,单词对中第一个单词的最后一个字母与最后一个单词的第一个字母匹配。但是,我们只会在列表的末尾添加单词,不同于你可以在开始或结束时,或者甚至在中间的某个地方添加对的例子。 因此,如果我们从一系列单词开始:

["cat","bat","cow","war","rot","tar"]
以及种子名单:

["tub"]
那么我们想:

link ["cat","bat","cow","war","rot","tar"] ["tub"]
给予:

["tub","bat","tar","rot"]
在这里,从列表[tub]开始,我们找到了以a b开头的第一个单词,因此我们可以将其添加到末尾以获取[tub,bat],然后搜索以t开头的剩余第一个单词以获取[tub,bat,tar],然后搜索以r开头的剩余第一个单词以获取[tub,bat,tar,rot],然后程序结束,因为没有以t开头的剩余单词

我们的第一次尝试,我认为与您上面的算法类似,可能是:

link :: [String] -> [String] -> [String]
link (wrd:wrds) chain
  | lastLetter == head wrd = link wrds (chain ++ [wrd])
  | otherwise              = link wrds chain
  where lastLetter = last (last chain)
link [] chain = chain
不幸的是,这给出了错误的答案:

> link ["cat","bat","cow","war","rot","tar"] ["tub"]
["tub","bat","tar"]
>
它忽略了rot,因为它在添加tar后只处理单词列表的尾部,并且没有剩下更多的单词。你需要它回到列表的开头,这就是你被卡住的地方

问题是,当您在bat上获得第一次成功匹配时,递归调用是:

link wrds (chain ++ [wrd])
=
link ["cow","war","rot","tar"] (["tub"] ++ ["bat"])
而不是:

link wrds (chain ++ [wrd])
=
link ["cat","cow","war","rot","tar"] (["tub"] ++ ["bat"])
不知何故,您需要包括已处理的不匹配单词列表,即[cat],以及以cow开头的单词列表的尾部

在Haskell中,如果您需要一些信息,比如您已经处理过的不匹配单词列表,您通常会传递这些信息 它作为一个额外的参数。所以,让我们重写链接以获取额外列表:

link' :: [String] -> [String] -> [String] -> [String]
link' unmatched (wrd:wrds) chain = ...
考虑到不匹配单词的初始列表将为空:

> link' [] ["cat","bat","cow","war","rot","tar"] ["tub"]
... | lastLetter == head wrd = link' [] (unmatched ++ wrds) (chain ++ [wrd])
现在,让我们弄清楚“链接”的定义。我们将从最简单的情况开始,否则的情况下,我们没有匹配当前的wrd。在本例中,我们将wrd添加到不匹配的单词列表中,并继续查找剩余的wrd:

另一方面,如果我们匹配,我们希望将单词添加到链中:

... | lastLetter == head wrd = link' ?? ?? (chain ++ [wrd])
但前两个论点应该是什么?好吧,我们想重新开始,看看列表中的所有单词,除了我们匹配的wrd。也就是说,我们希望查看所有不匹配的单词,以及其他WRD,因此我们希望:

... | lastLetter == head wrd = link' ?? (unmatched ++ wrds) (chain ++ [wrd])
这个调用的第一个参数是什么?好吧,我们重新开始,所以没有任何不匹配的词-不匹配的列表应该是空的:

> link' [] ["cat","bat","cow","war","rot","tar"] ["tub"]
... | lastLetter == head wrd = link' [] (unmatched ++ wrds) (chain ++ [wrd])
这给出了完整、更新的定义:

link' :: [String] -> [String] -> [String] -> [String]
link' unmatched (wrd:wrds) chain
  | lastLetter == head wrd = link' [] (unmatched ++ wrds) (chain ++ [wrd])
  | otherwise              = link' (unmatched ++ [wrd]) wrds chain
  where lastLetter = last (last chain)
那么终止案例呢:

link' unmatched [] chain = ???
这可能有点棘手。但是,请记住,如果我们匹配了一个单词,我们会跳回到开头:

link' [] (unmatched ++ wrds) (chain ++ [wrd])
如果至少剩下一个单词,即如果unmatched++wrds为非空,我们将继续使用非终止大小写。我们到达终止格的唯一方法是:1我们匹配最后一个可用的单词并使用空单词列表跳回开头,或2我们到达单词列表的末尾而没有匹配。在任何一种情况下,链都是完整的-在案例1中,单词列表中的所有单词都已成功添加到链中;在案例2中,单词列表非空,但无法成功添加任何单词。因此,在任何一种情况下,我们都希望停止并返回链,终止情况是:

link' unmatched [] chain = chain
当您使用这样一个额外的参数时,通常会在helper函数中进行封装,因此链接的最终修订定义如下所示:

link :: [String] -> [String] -> [String]
link wrds chain = link' [] wrds chain
  where
    link' unmatched (wrd:wrds) chain
      | lastLetter == head wrd = link' [] (unmatched ++ wrds) (chain ++ [wrd])
      | otherwise              = link' (unmatched ++ [wrd]) wrds chain
      where lastLetter = last (last chain)
    link' unmatched [] chain = chain
这就给出了正确的答案:

> link ["cat","bat","cow","war","rot","tar"] ["tub"]
["tub","bat","tar","rot"]
>

你能举例说明输入/输出吗?例如,f[1,5,4,3,5,6,1,7,7,9,3,11][6,10]=…?那么预期的结果是:[1,5,5,66,10],而我的输出是[5,66,10],因为我的函数一直在尾部,并失去了对旧头的关注,我想我不明白为什么你会得到一个无限列表1以外的任何东西,5与1和5都匹配-那么是什么导致了基本情况?我也不理解问题描述。您说您需要返回到列表的开头,但这可能是因为您没有以您需要的方式聚合您的输入,从而可以立即访问它。你说我需要从1到4再到5,那是什么意思?当你到4点的时候会发生什么?这些似乎是元组的第一部分;第二部分的意义是什么?尝试重新表述您的问题描述,使其描述问题,而不是迄今为止您的解决方案。当然,你可以单独描述。我添加了一个编辑,希望能帮助澄清一些事情,对不起,伙计们没有提供足够的信息。在阅读了这篇文章之后,它似乎非常有用。让我做一些挖掘,我会回复任何问题。但这正是我所说的。谢谢你以一种简单易懂的方式写作。