为什么Haskell代数数据类型“关闭”? [英] Why are Haskell algebraic data types "closed"?

查看:135
本文介绍了为什么Haskell代数数据类型“关闭”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我错了,纠正我,但好像Haskell中的代数数据类型在很多情况下都很有用,在这种情况下,您将使用面向对象语言的类和继承。但是有一个很大的区别:一旦声明了代数数据类型,就不能在其他地方扩展。它是关闭的。在OO中,您可以扩展已定义的类。例如:

  data可能a = Nothing |只是一个

没有办法,我可以在稍后添加另一个选项到这个类型而不用修改这个宣言。那么这个系统有什么好处?看起来OO的方式会更具可扩展性。

解决方案

ADT关闭的事实使写起来更容易总功能。

  mayToList :: Maybe a  - >>这些函数总是产生一个结果,对于它的类型的所有可能值, ; [a] 
maybeToList Nothing = []
maybeToList(只要x)= [x]

如果 Maybe 被打开,有人可以添加额外的构造函数,并且 mayToList 函数会突然中断。 / p>

在OO中,当您使用继承来扩展类型时,这不是问题,因为当您调用没有特定超载的函数时,它可以只需使用超类的实现。也就是说,如果 Student > printPerson(Person p)就可以调用 Student Person 的一个子类。



在Haskell中,通常使用封装和当需要扩展类型时,请键入类。例如:

  class Eq a where 
(==):: a - > a - > Bool

实例Eq Bool其中
False == False = True
False == True = False
True == False = False
True == True = True

实例方程a =>公式[a]其中
[] == [] = True
(x:xs)==(y:ys)= x == y&& xs == ys
_ == _ = False

现在, == 函数是完全开放的,你可以通过使它成为 Eq 类的一个实例来添加你自己的类型。






请注意,有关可扩展数据类型,但绝对不是Haskell的一部分。


Correct me if I'm wrong, but it seems like algebraic data types in Haskell are useful in many of the cases where you would use classes and inheritance in OO languages. But there is a big difference: once an algebraic data type is declared, it can not be extended elsewhere. It is "closed". In OO, you can extend already defined classes. For example:

data Maybe a = Nothing | Just a

There is no way that I can somehow add another option to this type later on without modifying this declaration. So what are the benefits of this system? It seems like the OO way would be much more extensible.

解决方案

The fact that ADT are closed makes it a lot easier to write total functions. That are functions that always produce a result, for all possible values of its type, eg.

maybeToList :: Maybe a -> [a]
maybeToList Nothing  = []
maybeToList (Just x) = [x]

If Maybe were open, someone could add a extra constructor and the maybeToList function would suddenly break.

In OO this isn't an issue, when you're using inheritance to extend a type, because when you call a function for which there is no specific overload, it can just use the implementation for a superclass. I.e., you can call printPerson(Person p) just fine with a Student object if Student is a subclass of Person.

In Haskell, you would usually use encapsulation and type classes when you need to extent your types. For example:

class Eq a where
   (==) :: a -> a -> Bool

instance Eq Bool where
  False == False = True
  False == True  = False
  True  == False = False
  True  == True  = True

instance Eq a => Eq [a] where
  []     == []     = True
  (x:xs) == (y:ys) = x == y && xs == ys
  _      == _      = False

Now, the == function is completely open, you can add your own types by making it an instance of the Eq class.


Note that there has been work on the idea of extensible datatypes, but that is definitely not part of Haskell yet.

这篇关于为什么Haskell代数数据类型“关闭”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆