非常简单的haskell程序,但我仍然有问题找到我的错误

时间:2017-11-10 19:51:14

标签: list haskell

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

大家好,这是我编写的一个非常简单的代码,我认为它应该做的很清楚,但它只是不起作用,我似乎无法找到解决方法。 我很感激每一个帮助,但请更正程序,因为现在我不想找到另一种方法来编写相同的程序,但找到我已经创建的错误 提前谢谢

3 个答案:

答案 0 :(得分:8)

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

有两种类型的列表构造函数

  1. 空列表[];和
  2. 缺点 (x:xs)(注意圆括号)。
  3. 您的第一个条款是正确的:您匹配两个列表。

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

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

    但是现在我们将讨论其他问题。

    最后一个子句是对两个参数使用缺点的示例。所以你应该把它写成:

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

    请注意,我们不会在递归调用中编写andX [xs] [ys](因为这会导致构造singelton列表),但我们会传递第一个和第二个列表的 tails 。 / p>

    现在我们获得:

    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]]
    

答案 1 :(得分:2)

让我解释一下这段代码:

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]是仅包含一个元素的列表,因此如果列表大小不同,您将遇到模式匹配失败。< / p>

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]那样读取它是&#34;添加元素x,添加元素y然后放入列表的其余部分andX [xs] [ys]&#34;

答案 2 :(得分:1)

[x:xs]更改为(x:xs),并将[y:ys]更改为<{1}}。

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

您也不想为案例2和3创建嵌套列表,因此将[xs]更改为xs,将[ys]更改为