StandardML 中一组集合的类型冲突问题

发布于 2024-11-27 12:26:23 字数 2109 浏览 1 评论 0原文

我正在阅读在线书籍“计算类别理论”http:// /www.cs.man.ac.uk/~david/categories/book/book.pdf 我在本书中的问题 2.10 中遇到了一些问题。特别是幂集的定义。

abstype 'a Set = set of 'a list
  with val emptyset = set([])
    fun is_empty(set(s)) = length(s)=0
    fun singleton(x) = set([x])
    fun disjoint_union(set(s),set(nil))=set(s) | 
      disjoint_union(set(s),set(t::y))=
      if list_member(t,s) then disjoint_union(set(s),set(y)) 
      else disjoint_union(set(t::s),set(y))
    fun union(set(s),set(t)) = set(append(s,t))
    fun member(x,set(l)) = list_member(x,l)
    fun remove(x,set(l)) = set(list_remove(x,l))
    fun singleton_split(set(nil)) = raise empty_set
      | singleton_split(set(x::s)) =(x,remove(x,set(s)))
    fun split(s) = let val (x,s') = singleton_split(s) in (singleton(x),s') end
    fun cardinality(s) = if is_empty(s) then 0 else
      let val (x,s') = singleton_split(s) in 1 + cardinality(s') end
    fun image(f)(s) = if is_empty(s) then emptyset else
      let val (x,s') = singleton_split(s) in
      union(singleton(f(x)),image(f)(s')) end
    fun display(s)= if is_empty(s) then [] else
      let val (x,s') = singleton_split(s) in x::display(s') end
    fun cartesian(set(nil),set(b))=emptyset | 
      cartesian(set(a),set(b)) = let val (x,s') = singleton_split(set(a)) 
      in union(image(fn xx => (x,xx))(set(b)),cartesian(s',set(b))) end
    fun powerset(s) = 
      if is_empty(s) then singleton(emptyset) 
      else let 
      val (x,s') = singleton_split(s) 
      val ps'' = powerset(s') 
      in union(image(fn t => union(singleton(x),t))(ps''),ps'') end
end

powerset 函数由附录 D 中的答案给出。然后我创建一个集合的 powerset:

val someset=singleton(3); (*corresponds to the set {3}*)
val powerset=powerset(someset); (* should result in {{},{3}} *)
val cardinality(someset); (*returns 1*)
val cardinality(powerset); (*throws an error*)

! Type clash: expression of type
!    int Set Set
! cannot have type
!    ''a Set

为什么我可以计算一组整数的基数,但不能计算一组整数的基数?我做错了什么吗?

I am perusing the online book "Computational Category Theory" http://www.cs.man.ac.uk/~david/categories/book/book.pdf and I am having some problems with problem 2.10 in this book. Particularly, with the definition of the powerset.

abstype 'a Set = set of 'a list
  with val emptyset = set([])
    fun is_empty(set(s)) = length(s)=0
    fun singleton(x) = set([x])
    fun disjoint_union(set(s),set(nil))=set(s) | 
      disjoint_union(set(s),set(t::y))=
      if list_member(t,s) then disjoint_union(set(s),set(y)) 
      else disjoint_union(set(t::s),set(y))
    fun union(set(s),set(t)) = set(append(s,t))
    fun member(x,set(l)) = list_member(x,l)
    fun remove(x,set(l)) = set(list_remove(x,l))
    fun singleton_split(set(nil)) = raise empty_set
      | singleton_split(set(x::s)) =(x,remove(x,set(s)))
    fun split(s) = let val (x,s') = singleton_split(s) in (singleton(x),s') end
    fun cardinality(s) = if is_empty(s) then 0 else
      let val (x,s') = singleton_split(s) in 1 + cardinality(s') end
    fun image(f)(s) = if is_empty(s) then emptyset else
      let val (x,s') = singleton_split(s) in
      union(singleton(f(x)),image(f)(s')) end
    fun display(s)= if is_empty(s) then [] else
      let val (x,s') = singleton_split(s) in x::display(s') end
    fun cartesian(set(nil),set(b))=emptyset | 
      cartesian(set(a),set(b)) = let val (x,s') = singleton_split(set(a)) 
      in union(image(fn xx => (x,xx))(set(b)),cartesian(s',set(b))) end
    fun powerset(s) = 
      if is_empty(s) then singleton(emptyset) 
      else let 
      val (x,s') = singleton_split(s) 
      val ps'' = powerset(s') 
      in union(image(fn t => union(singleton(x),t))(ps''),ps'') end
end

The powerset function is given from the answers in Appendix D. I then create the powerset of a set:

val someset=singleton(3); (*corresponds to the set {3}*)
val powerset=powerset(someset); (* should result in {{},{3}} *)
val cardinality(someset); (*returns 1*)
val cardinality(powerset); (*throws an error*)

! Type clash: expression of type
!    int Set Set
! cannot have type
!    ''a Set

Why can I calculate the cardinality of a set of integers, but not of a set of sets of integers? Am I doing something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

真心难拥有 2024-12-04 12:26:23

问题在于如何计算集合的基数。

为了计算集合的基数,您需要遍历每个元素,删除它以及同一元素的所有其他出现,每次删除将计数加一。

特别是,“以及同一元素的所有进一步出现”部分是失败的。

int 类型是一种相等类型,因此在这种情况下,比较两个整数以查看它们是否相同效果很好。

然而,int Set 类型不是相等类型。这意味着 list_remove 调用将不起作用,因为它无法比较两个 int Set

您可能会问这是为什么?好吧,考虑以下内容:

val onlythree = singleton 3; (* {3} *)
val onlythree_2 = union (onlythree, onlythree); (* {3} U {3} = {3} *)

这两个集合都表示相同的集合,但内部表示不同:

onlythree   = set [3]
onlythree_2 = set [3, 3]

因此,如果您允许标准相等运算符直接对它们进行操作,您会发现它们会有所不同,即使它们代表同一个集合。那可不好。

解决这个问题的一种方法是确保每当您从集合操作返回结果时,集合始终由其“规范表示”表示。不过,我不确定这通常是否可行。

The trouble lies in how you count the cardinality of the set.

In order to count the cardinality of the set, you go through each element, remove it as well as all further occurrences of the same element, increasing the count by one for each such removal.

In particular, the "as well as all further occurrences of the same element" part is what is failing.

The int type is an equality type, so in that case comparing two integers to see if they're the same works out well.

The int Set type, however, is not an equality type. This means, the list_remove call will not work, as it cannot compare two int Sets.

Why is this, you might ask? Well, consider the following:

val onlythree = singleton 3; (* {3} *)
val onlythree_2 = union (onlythree, onlythree); (* {3} U {3} = {3} *)

These two sets both represent the same set, however the internal representations differ:

onlythree   = set [3]
onlythree_2 = set [3, 3]

So, if you allowed the standard equality operator to work directly on these, you'd get that they'd be different, even though they represent the same set. That's no good.

One way of remedying this could be ensuring that a set always is represented by its "canonical representation" whenever you return a result from a set operation. I'm not sure if this is possible to do in general, however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文