【问题标题】:Haskell - Concatenation of ListsHaskell - 列表的串联
【发布时间】:2014-04-22 13:13:29
【问题描述】:

我尝试连接两个列表,使得结果列表中的元素只出现一次。 我不想使用预定义的函数,因为那样太容易了。所以因为我正在学习haskell,所以我编写了以下代码:

import Data.List

add :: [Int] -> [Int] -> [Int]

add xs ys = zs ++ ws
        where
        zs = if elem x (x:xs) == True then x:(elem x xs)
             else elem x xs
        ws = if elem y (y:ys) == True then y:(elem y ys)
             else elem y ys

我只使用预定义的函数 elem 告诉我一个元素是否出现在列表中。 我的想法是先获取一个列表并使用“elem”来确定列表 xs 的第一个元素 x 是否多次存在于列表中。如果是这样,那么我使用该 x 并使用 ":"-operator 和 (elem x xs) 建立一个新列表,直到检查所有元素。 我对第二个列表做同样的事情。 如果完成,那么我使用“++”- 运算符将无重复列表与 zs ++ ws 连接起来。所以当我编译它时,ghci 告诉我 x 和 y 不在范围内。我的错误在哪里?

【问题讨论】:

  • 这里的情况很混乱。例如,elem x xs 的类型是Bool,所以表达式x:(elem x xs) 没有任何意义。此外,x 这个词突然出现——你还没有定义它是什么。
  • 好吧,xy 确实不在范围内,您在使用它们之前不要在任何地方定义它们。在您看来,xy 应该是什么?也许你的意思是你的模式匹配是add (x:xs) (y:ys)
  • 我尝试用 elem x (x:xs) 表达,我检查列表 xs 的第一个元素是否在列表中出现多次。因此,x 和 y 应该是列表 xs 和 ys 的第一个元素。
  • 不,xy 是列表 x:xsy:ys 的第一个元素。

标签: haskell


【解决方案1】:

你没有给出这个函数的预期输入/输出的例子,所以我将使用你给出的定义 -

“连接两个列表,使得结果列表中的元素只出现一次。”

似乎有一种简单的方法可以做到这一点 -

  1. 连接两个列表。
  2. 删除重复项。

因此,假设您有一个函数unique :: [Int] -> [Int],它可以从列表中删除重复项(同时保持元素有序)。那么你想要的就这么简单

add :: [Int] -> [Int] -> [Int]
add xs ys = unique (xs ++ ys)

所以您已将问题简化为编写unique 函数的简单问题。你能做到吗?

【讨论】:

    【解决方案2】:

    我认为 Chris 的解决方案是可行的方法。但是为了教学,我会讨论你方法中的一些问题。首先,为了在您的函数add 中引用xy,必须在某处定义它们。我怀疑你的意图是:

    add (x:xs) (y:ys) = ...
    

    现在您可以在函数定义中使用xxsyys。现在任何时候你都想写这样的东西:

    if condition == True then...
    

    知道写起来更简单更清晰

    if condition then...
    

    所以我认为你打算写这样的东西:

    add (x:xs) (y:ys) = zs ++ ws
        where
            zs = if elem x xs then xs
                              else x:xs
            ws = if elem y ys then ys
                              else y:ys
    

    除了您还想进行某种递归以确保xsys 中的任何元素都不会重复。但是,递归两个列表将非常尴尬且难以做到。这就是为什么 Chris 的答案更好,而且是更接近 Haskell 的方法。

    还要注意,而不是

    elem x xs
    

    写起来更易读

    x `elem` xs
    

    【讨论】:

    • 更重要的是,elem x xselem x ys 都必须检查。 y 也是如此。
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2018-02-17
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 2021-09-19
    • 1970-01-01
    相关资源
    最近更新 更多