极其简单的Haskell程序,但我仍然有问题找我的错误

问题描述:

andX :: [a] -> [a] -> [a] 
andX []   []  = [] 
andX [xs]  []  = [xs] 
andX []   [ys] = [ys] 
andX [x:xs] [y:ys] = [x,y] : andX [xs] [ys] 

嗨,大家好,这是一个非常简单的代码我写的,我认为它应该做的是明确的,但它只是不工作,我似乎无法找到一种方法要解决这个问题。 我很感激每一个帮助,但还是请修正程序如因为现在我不希望找到另一种方式来写相同的程序,但发现我已经创建 由于错误提前极其简单的Haskell程序,但我仍然有问题找我的错误

+0

你的模式匹配,并不意味着你在想什么。 '[x:xs]'是一个元素的列表,该元素本身就是一个列表,其中至少有一个元素“x”,后面是列表“xs”的其余部分。你可能想要的是'(x:xs)'和'(y:ys)'相同。 –

+0

让我知道如果你不明白我的答案 –

变化[x:xs](x:xs),和[y:ys]一样。

此外,你不能预先列表列表;您将元素添加到列表中。因此请将[x, y]:更改为x:y:

你不想创建情况2和3,无论是嵌套列表,所以更改[xs]只是xs,与同为[ys]

让我解释一下这段代码:

andX :: [a] -> [a] -> [a] 
andX []   []  = [] 
andX xs   []  = xs 
andX []   ys  = ys 
andX (x:xs) (y:ys)  = x : y : andX xs ys 

例如,看着你的答案,你想这样:

andX [1,2,3] [4,5,6] 
=> [1,4,2,5,3,6] 

andX [1,4,2,5] [1,3,0,2,5,7] 
=> [1,1,4,3,2,0,5,2,5,7] 

看看你的企图(这是足够接近)

andX :: [a] -> [a] -> [a] 
andX []   []  = [] 
andX [xs]  []  = [xs] 
andX []   [ys] = [ys] 

这里,前三种情况是好的,但要小心[xs][ys]是只有一个元素列表,所以你会在得到如果列表具有不同的大小,模式匹配失败。

andX [x:xs] [y:ys] = [x,y] : andX [xs] [ys] 

这里是我们列出的名单中最好的问题,首先[x:xs] :: [[a]],你必须使用()当你正在做的模式匹配。 然后[x,y] : andX [xs] [ys]是错误的,再次,类型不匹配,您试图将[a]添加到[a],并且您只需添加a元素,您可以像x : y : andX [xs] [ys]这样做,如果您阅读它是“add element x,add元素y然后把其余的列表andX [xs] [ys]

+0

如果列表之间的差异超过一个元素,这仍然是错误的。 –

+0

'和X [1,4,2,5] [1,3,0,2,5,7]'。 –

这里有一些问题,但最重要的可能是列表语法是错误的。

有两种类型的列表构造

  1. 空单[];和
  2. the cons(x:xs)(注意括号内)。

您的第一个条款因此是正确的:您匹配两个空的列表。

第二类和第三类语法正确的,但它意味着你匹配清单:一个项目的列表。这是因为Haskell具有语法糖:[x](x:[])的简称。我很确定你不想匹配一个单身人士名单,但任何名单。如果你想这样做,你可以简单地写:

andX xs [] = ... 
andX [] ys = ... 

但现在会出现其他问题,我们将在后面讨论。

最后一个条款是两个参数都使用缺点的示例。所以,你应该把它写成:

andX (x:xs)(y:ys) = [x,y] : andX xsys

请注意,我们不写在递归调用andX [xs] [ys](因为这会导致在构建singelton列表),但我们通过尾巴第一和第二列表

所以,现在我们得到:

andX :: [a] -> [a] -> [a] 
andX []  []  = [] 
andX xs  []  = xs 
andX []  ys  = ys 
andX (x:xs) (y:ys) = [x,y] : andX xs ys 

,但它仍然是不正确。基本上有两个我能想到的应用程序。

“合并”两个列表

如果要合并在这个意义上,我们得到以下形式的列表中列出:

[x1,y1,x2,y2,x3,...] 

那么我们可以不写电感情况下:

andX (x:xs) (y:ys) = [x,y] : andX xs ys 

因为这里作为回报,我们采取[x,y]一个输出的第一要素。不过,我们可以这样写:

andX (x:xs) (y:ys) = x : y : andX xs ys 

现在我们发出两个项目xy作为单独项目,其次是递归调用。在这种情况下,代码片段是:

andX :: [a] -> [a] -> [a] 
andX []  []  = [] 
andX xs  []  = xs 
andX []  ys  = ys 
andX (x:xs) (y:ys) = x : y : andX xs ys 

:基于您的代码

Prelude> andX [1,4,2,5] [1,3,0,2,5] 
[1,1,4,3,2,0,5,2,5] 

构建子列表

要返回一个列表的列表。但是你的输出类型说[a]。如果你想返回一个列表清单,它应该是[[a]]

andX :: [a] -> [a] -> [[a]] 
andX []  []  = [] 
andX xs  []  = xs 
andX []  ys  = ys 
andX (x:xs) (y:ys) = [x,y] : andX xs ys 

所以现在我们有名单的列表,每个子列表包含了从第一列表中的一个从第二列表中的元素,和。然而,一个问题是第二个和第三个条款使用xsys作为输出。我们不能这样做,因为我们期望列表的列表。我们可以通过它重写来解决这个:

andX :: [a] -> [a] -> [[a]] 
andX []  []  = [] 
andX (x:xs) []  = [x] : andX xs [] 
andX []  (y:ys) = [y] : andX [] ys 
andX (x:xs) (y:ys) = [x,y] : andX xs ys 

Prelude> andX [1,4,2,5] [1,3,0,2,5] 
[[1,1],[4,3],[2,0],[5,2],[5]] 
+0

现在你的答案是完美的,这当然是一个加号...... –

+0

非常感谢你这是非常丰富的信息,我学到了很多东西! –