如何将我在OOP的想法转换为Haskell? [英] How to convert my thoughts in OOP to Haskell?

查看:109
本文介绍了如何将我在OOP的想法转换为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屋!

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