如何将我在OOP的想法转换为Haskell? [英] How to convert my thoughts in OOP to Haskell?
问题描述
所以我这样做:
class ElementClass
数据E1 = E1字符串
实例ElementClass E1
数据E2 = E2 Int
实例ElementClass E2
data Element = forall e。 (ElementClass e)=>元素e
data容器=容器[元素]
直到我需要处理与单独的元素。由于forall,函数f :: Element - > IO()没有办法知道它是什么元素。
什么是正确的方法来做到这一点在Haskell风格?
知道元素究竟是什么
要知道,你当然应该使用一个简单的ADT
数据元素'= E1Element E1
| E2Element E2
| ...
通过这种方式,您可以对它在容器中的哪一个进行模式匹配。 / p>
现在,与
发生冲突的人可能会创建自己的元素类型并成为持有我的货柜
必须冲突!当允许其他人将新类型添加到元素列表中时,无法安全地匹配所有可能的情况。所以,如果你想匹配,唯一正确的做法是拥有一组封闭的可能性,就像ADT给你的那样。
OTOH拥有像你一样的存在记住,允许类型的类是开放的。没关系,但仅仅是因为确切的类型实际上不可访问,而只是由全部定义的通用接口。元素类e
。
Haskell中的存在确实让人有些皱眉,因为它们是如此的OO-ish。但有时候这是非常正确的事情,你的应用程序可能是一个好例子。
For example, I have a container type to hold elements with common character. And I also provide some types to be the element. And I also want this function to be easily extended (others could make their own element type and be hold by my container).
So I do:
class ElementClass
data E1 = E1 String
instance ElementClass E1
data E2 = E2 Int
instance ElementClass E2
data Element = forall e. (ElementClass e) => Element e
data Container = Container [Element]
This is fine until I need to deal with the element individually. Due to forall, function "f :: Element -> IO ()" has no way to know what element it is exactly.
What is the proper way to do this in Haskell style?
to know what element it is exactly
To know that, you should of course use a simple ADT
data Element' = E1Element E1
| E2Element E2
| ...
this way, you can pattern-match on which one it is in your container.
Now, that clashes with
others could make their own element type and be hold by my container
and it must clash! When other people are allowed to add new types to the list of elements, there's no way to safely match all possible cases. So if you want to match, the only correct thing is to have a closed set of possibilities, as an ADT gives you.
OTOH, with an existential like you originally had in mind, the class of allowed types is open. That's ok, but only because the exact type isn't in fact accessible but only the common interface defined by forall e. ElementClass e
.
Existentials are indeed a bit frowned-upon in Haskell, because they are so OO-ish. But sometimes this is quite the right thing to do, your application might be a good case.
这篇关于如何将我在OOP的想法转换为Haskell?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!