删除集合中的一个元素

lee*_*dly 4 haskell set abstract-data-type

我试图从集合中删除一个元素,但我似乎无法正确理解语法。数据类型定义如下:

data Menge el = Menge [el] deriving (Eq, Ord, Show)
Run Code Online (Sandbox Code Playgroud)

函数是:

loeschen :: (Ord el) => el -> Menge el -> Menge el
loeschen el (Menge []) = Menge []
loeschen el (Menge (x:xs))
    | el == x = Menge xs
    | otherwise = Menge (x : loeschen el (Menge xs))
Run Code Online (Sandbox Code Playgroud)

错误说

无法匹配预期类型:[el] 与实际类型:Menge el

之后我尝试了该部分的多个版本(x:),但总是遇到相同的错误。

Wil*_*sem 9

问题是您loeschen el (Menge xs)返回 a Menge,因此您不能将其与 一起使用x : loeschen el (Menge xs),因为它需要一个列表作为第二个参数。

然而,你可能把这个问题过于复杂化了。您只需打开列表一次,删除项目,然后将结果添加到 a 中Menge,例如:

loeschen :: Eq el => el -> Menge el -> Menge el
loeschen el (Menge xs) = Menge (go xs)
  where
    go [] = []
    go (x : xs)
      | el == x = xs
      | otherwise = x : go xs
Run Code Online (Sandbox Code Playgroud)

然而,从列表中删除元素已经用 实现delete :: Eq a => a -> [a] -> [a],因此我们可以将其实现为:

import Data.List (delete)

loeschen :: Eq el => el -> Menge el -> Menge el
loeschen el (Menge xs) = Menge (delete el xs)
Run Code Online (Sandbox Code Playgroud)


ama*_*loy 5

Willem Van Onsem的回答是实现这个功能的好方法;我肯定会选择这两种方式之一。然而,从你的问题来看,在我看来,你所面临的症结是如何实现 type 的递归函数Menge el -> Menge el,而其他答案在某种意义上通过委托给 type 的递归函数来避免这个问题[el] -> [el]。完全有可能做您想做的事情:只需确保Menge在必要时将其包装和解开到列表中:

loeschen :: (Ord el) => el -> Menge el -> Menge el
loeschen el (Menge []) = Menge []
loeschen el (Menge (x:xs))
    | el == x = Menge xs
    | otherwise = let Menge xs' = loeschen el (Menge xs)
                  in Menge (x : xs')
Run Code Online (Sandbox Code Playgroud)