1

我一直在试图弄清楚如何使 staticText 元素调整大小以适应 wxHaskell 的内容。据我所知,这是 wxWidgets 中的默认行为,但 wxHaskell 包装器专门禁用了此行为。但是,创建新元素的库代码让我很困惑。谁能解释这段代码的作用?

staticText :: Window a -> [Prop (StaticText ())] -> IO (StaticText ())
staticText parent props
  = feed2 props 0 $
    initialWindow $ \id rect ->
    initialText   $ \txt -> \props flags ->
    do t <- staticTextCreate parent id txt rect flags {- (wxALIGN_LEFT + wxST_NO_AUTORESIZE) -}
       set t props
       return t

我知道feed2 x y f = f x y,并且 initialWindow 的类型签名是

initialWindow :: (Id -> Rect -> [Prop (Window w)] -> Style -> a) -> [Prop (Window w)] -> Style -> a

并且 initialText 的签名是

initialText :: Textual w => (String -> [Prop w] -> a) -> [Prop w] -> a

但我就是无法理解所有的 lambdas。

4

2 回答 2

2

在 Haskell 中,一切都是嵌套的 lambda!\txt -> \props flags -> do {...}与 相同\txt props flags -> do {...},两者实际上都是

\txt -> \props -> \flags -> do {...}

这里有点令人困惑的是,这\txt props flags似乎是许多论点:

initialText :: ...=> (String -> [Prop w] -> a) -> ...

似乎采用 2 参数函数,我们给它一个三参数 lambda。但请记住:实际上,每个函数只接受一个参数,其他一切都是通过柯里化完成的。在这种情况下,a又是一个函数类型,所以它实际上应该改为

initialText :: Textual w => (String -> [Prop w] -> b -> c) -> [Prop w] -> b -> c

这不是乐趣的结束。to 的参数initialWindow似乎只有很少的参数,2 而不是 4,但事实并非如此:我们只给出initialWindow了它的第一个参数,结果是一个函数首先接受更多参数[Prop w](在这种情况下,[Prop(Window w)]initialWindow签名)。然后它返回a,我们将其重写为b->c; 在这种情况下,initialWindow需要的是Style -> a.

所以initialText这个应用程序中的实际签名是

(String -> [Prop(Window w)] -> Style -> c) -> [Prop w] -> Style -> c
于 2012-11-17T22:47:59.987 回答
2

我没用过的 WX 库,内部似乎使用了奇怪的回调或延续传递样式。这个阴影props以一种令人困惑的方式,让我重命名那个傻瓜:

staticText1 :: Window a -> [Prop (StaticText ())] -> IO (StaticText ())
staticText1 parent propsTopLevel
  = feed2 propsTopLevel 0 $
    initialWindow $ \id rect ->
    initialText   $ \txt -> \propsParam flags ->
    do t <- staticTextCreate parent id txt rect flags
       set t propsParam
       return t

没有 ($) 我可以使用括号:

staticText2 :: Window a -> [Prop (StaticText ())] -> IO (StaticText ()) staticText2 parent propsTopLevel = feed2 propsTopLevel 0 (initialWindow (\id rect -> initialText (\txt -> \propsParam flags -> do t <- staticTextCreate parent id txt rect flags set t props return t)))

诸如此类的 lambda\text -> \props flags ->可以命名为:

staticText3 :: Window a -> [Prop (StaticText ())] -> IO (StaticText ())
staticText3 parent propsTopLevel = initialWindow myWindow propsTopLevel 0
  where makeWindow id rect = initialText myText
          where myText txt propsParam flags = do
                  t <- staticTextCreate parent id txt rect flags
                  set t propsParam
                  return t

staticText3我使用嵌套词法范围作为参数名称。让我更明确一点:

staticText4 :: Window a -> [Prop (StaticText ())] -> IO (StaticText ())
staticText4 = makeWindowTextStatic where
  makeWindowTextStatic parent propsTopLevel = initialWindow (makeTextStatic parent) propsTopLevel 0
  makeTextStatic parent id rect = initialText (makeStatic parent id rect)
  makeStatic parent id rect txt propsParam flags = do
    t <- staticTextCreate parent id txt rect flags
    set t propsParam
    return t

这是否足够清楚以跟随流程?我还没有尝试去理解initialWindowinitialText他们自己。

于 2012-11-17T23:38:14.747 回答