【问题标题】:How Do I implement a Set as an abstract data type in Haskell?如何在 Haskell 中将 Set 实现为抽象数据类型?
【发布时间】:2022-11-30 23:16:18
【问题描述】:

我必须在 Haskell 中将集合实现为抽象数据类型。任务如下:

集合对一组元素建模。集合是空集或递归地由一个元素和集合的其余部分组成是有效的。 将定义函数 isEmpty、contains、add、remove。

  • 函数 isEmpty 检查集合是否为空。
  • contains 采用一个集合和一个元素,并指示该集合是否包含该元素。
  • add 接受一个集合和一个元素,如果该元素不在集合中,则将其添加到集合中。尚未包含在集合中
  • remove 函数采用一个集合和一个元素,如果该元素已在集合中,则从集合中删除该元素。如果元素不是集合的一部分,则函数返回错误。

我正在为任务的递归部分而苦苦挣扎,我不知道。我该如何具体实施“包含”?

module Set (Set(EmptySet, MkSet), isEmpty, contains, add, remove)
    where
        
data Set a = EmptySet | MkSet a (Set a)
    deriving (Show, Eq, Enum, Ord, Read)

isEmpty :: Set a -> Bool
isEmpty EmptySet = True
isEmpty (MkSet a as) = False

contains :: Set a -> a -> Bool
contains EmptySet = error "no element in set."
contains (MkSet a as) a = True
contains (MkSet a as) b = False

add :: a -> Set a -> Set a
add a as = (MkSet a as)

remove :: Set a -> Set a
remove EmptySet = error "No remove operation on empty set allowed."
remove (MkSet a as) = as

(https://i.stack.imgur.com/W8kSj.png)

【问题讨论】:

标签: haskell haskell-platform


【解决方案1】:

两次使用模式变量a的模式contains (MkSet a as) a在文献中被称为非线性模式。 Haskell 中不允许使用非线性模式。相反,您必须像这样明确地检查相等性:

contains (MkSet a as) b
  | a == b = ...
  | otherwise = ...

这还需要在类型签名中添加 contains :: Eq a => Set a -> a -> Bool

请注意,ab是不同的变量,并不一定意味着它们在匹配时必须赋不同的值。

其次,您的案例 contains (MkSet a as) b = False 没有考虑到该元素可能包含在 as 中(提示:使用递归)。

第三,询问元素是否在空集中不是错误(感谢 chepner)。在这种情况下,它应该只返回False

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 2015-05-24
    • 2018-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多