首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell - Typeclass实例列表

Haskell - Typeclass实例列表
EN

Stack Overflow用户
提问于 2012-10-08 08:34:11
回答 2查看 3.8K关注 0票数 13

我是Haskell的新手,为了变得更好,我正在试着做一个简单的web服务器。我想让我表示页面的方式是可扩展的,所以我的想法是使网页成为可呈现数据的列表(就像如何在Java中创建实现某个接口的对象列表),其中

代码语言:javascript
复制
class Renderable a where
    render :: a -> IO String

不幸的是,我了解到列表必须是一个具体的类型,所以我只能创建一种类型的可呈现数据的列表。此外,似乎不可能创建受类型类约束的数据,所以我不能创建像RenderList数据这样的数据。我的临时解决方案是这样的:

代码语言:javascript
复制
myPage =
    [render $ someData
    ,render $ someMoreData
    ,render $ someOtherData
    ...
    ]

但这让人感觉很尴尬,使得使用类型类没有任何好处,而且感觉应该有更好的方法。所以我想知道有什么方法可以让我的东西更整洁,更符合标准的Haskell实践,并且仍然很容易扩展?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-08 10:57:44

您正在尝试实现一种面向对象的设计风格。例如,在Java语言中,只要有一个List<Renderable>,就一切都准备好了。这种设计风格在Haskell中有点不自然;您需要为有界存在类型创建一个包装器类型,如existential types的Haskell wiki页面所示。例如:

代码语言:javascript
复制
class Renderable_ a where
  render :: a -> IO String

data Renderable = forall a. Renderable_ a => Renderable a
instance Renderable_ Renderable where
  render (Renderable a) = render a

然后,您可以拥有一个Renderable列表,您可以随心所欲地呈现该列表。正如我所说的,这是一种在Haskell中不太自然的OO风格。你可以通过重新考虑你的数据结构来避免这种情况。你说你“想让你表示页面的方式是可扩展的”;考虑用其他的方式来实现。

无关:我猜render不需要生成IO String操作。如果可以的话,尽量把IO排除在设计的核心之外。

票数 13
EN

Stack Overflow用户

发布于 2012-10-08 09:11:56

在haskell heterogenous collections上查看此页面。它提供了几种方法的想法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12774056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档