我是Haskell的新手,为了变得更好,我正在试着做一个简单的web服务器。我想让我表示页面的方式是可扩展的,所以我的想法是使网页成为可呈现数据的列表(就像如何在Java中创建实现某个接口的对象列表),其中
class Renderable a where
render :: a -> IO String不幸的是,我了解到列表必须是一个具体的类型,所以我只能创建一种类型的可呈现数据的列表。此外,似乎不可能创建受类型类约束的数据,所以我不能创建像RenderList数据这样的数据。我的临时解决方案是这样的:
myPage =
[render $ someData
,render $ someMoreData
,render $ someOtherData
...
]但这让人感觉很尴尬,使得使用类型类没有任何好处,而且感觉应该有更好的方法。所以我想知道有什么方法可以让我的东西更整洁,更符合标准的Haskell实践,并且仍然很容易扩展?
谢谢。
发布于 2012-10-08 10:57:44
您正在尝试实现一种面向对象的设计风格。例如,在Java语言中,只要有一个List<Renderable>,就一切都准备好了。这种设计风格在Haskell中有点不自然;您需要为有界存在类型创建一个包装器类型,如existential types的Haskell wiki页面所示。例如:
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排除在设计的核心之外。
发布于 2012-10-08 09:11:56
在haskell heterogenous collections上查看此页面。它提供了几种方法的想法。
https://stackoverflow.com/questions/12774056
复制相似问题