假设我有以下函数:
loadDialog :: String -> IO MyDialog
loadDialog file = do
Just ui <- xmlNew file
MyDialog
<$> xmlGetWidget ui castToWindow "w"
<*> xmlGetWidget ui castToButton "b"
在哪里
xmlGetWidget :: WidgetClass widget => GladeXML -> (GObject -> widget) -> String -> IO widget
现在我想捕捉以下xmlNew/xmlGetWidget的使用模式:
widgetBinder :: WidgetClass widget => FilePath -> IO ((GObject -> widget) -> String -> IO widget)
widgetBinder file = do
Just ui <- xmlNew file
return $ xmlGetWidget ui
这应该让我可以写:
loadDialog file = do
bind <- widgetBinder file
MyDialog
<$> bind castToWindow "w"
<*> bind castToButton "b"
问题是,它无法通过类型检查(具体错误请看这里)。我认为可以明确地为绑定提供通用签名,但似乎对于单子绑定不适用,因为即使使用RankNTypes,以下代码也无法通过类型检查(错误请看这里):
loadDialog file = do
bind :: WidgetClass w => (GObject -> w) -> String -> IO w
<- widgetBinder file
MyDialog
<$> bind castToWindow "w"
<*> bind castToButton "b"
我能帮忙做些什么吗?