Java桌面应用程序通过RPC公开其Swing GUI的类/包含层次结构。我正在构建一个连接到应用程序的Haskell客户端。目标是能够在Haskell端的数据结构上执行诸如“查找所有宽度小于w,位于屏幕矩形r内的按钮”之类的查询。
我不知道如何最好地表示结构,特别是在继承/子类型方面。我试过两种方法。第一项:
data Component = Component
{
componentId::Int,
pos::(Int,Int),
dim::(Int,Int),
componentType::ComponentType,
children::[Component]
}
data ComponentType =
ButtonComponent Button
-- other component types here
|OtherComponent
data Button = Button
{
buttonText::Text
-- other button attributes here
}
我还在考虑使用存在型类型的第二解,以及可键入的实现“下传”的方法:
data Component = Component
{
componentId::Int,
pos::(Int,Int),
dim::(Int,Int),
children::[AnyComponent]
} deriving Typeable
data AnyComponent = forall a . ( Typeable a, HasComponent a ) => AnyComponent a
class HasComponent a where
base :: a -> Component
downcast :: Typeable b => a -> Maybe b
instance HasComponent Component where
base = id
downcast = cast -- cast function is from Data.Typeable
instance HasComponent AnyComponent where
base (AnyComponent a) = base a
downcast (AnyComponent a) = cast a
data Button = Button
{
buttonComponent:: Component, -- pointer to "superclass" info
buttonText::Text
-- other button attributes here
} deriving Typeable
instance HasComponent Button where
base = buttonComponent
downcast = cast
什么样的解决方案才是更地道的Haskell?有没有更好的解决办法?
发布于 2013-04-09 05:09:26
编辑:用Haskell忠实地表示OO语义目前是不可能的。特别是,方法解析可以通过类型类和实例来模拟(但不是很容易,也不是很忠实)。这个纸非常丰富地介绍了当前的最佳实践,以及未来可能的发展。
这里有一种可能,类似于您的第一个解决方案:
data ComponentClass a
= ComponentClass {
...
, comSubclass :: a
...
}
type Component = ComponentClass ()
data ButtonClass a
= ButtonClass {
, buttonText :: Text
, btSubclass :: a
...
}
type Button = ComponentClass (ButtonClass ())
如果我认为一个简单的层次很适合我的问题域(但不一定要在另一种语言中反映OO ),我就会这么做。但是,如果需要跟踪深度层次结构或多个超类(如Python),则此策略不能很好地工作。
另一个缺点是,您不能将任意ComponentClass a
解构为它的子类型a
。只有事先知道a
的类型,才能做到这一点。但是,您可以使用动态类型来解决这个问题,例如通过Typable
。
请注意,您还可以在向上的方向表示等级:
data ButtonClass a
= ButtonClass {
btText :: Text
, btSuperClass :: a
}
type Button = ButtonClass ComponentClass
然后,您可以“向下类层次结构”构建每个对象,直到您发现最具体的类型来封装它。
还请注意,Gtk2Hs使用类似于第二种策略的类型化策略来表示Gtk的类层次。也许看一看它的源代码会很有说服力,甚至只是浏览它的文件上的黑客。
最后,用Exception
实现的GHC
等级非常有趣,尽管我不认为它对你的帮助不如上面的任何一个
https://codereview.stackexchange.com/questions/11715
复制相似问题