1

wxHaskell を使用して staticText 要素のサイズをコンテンツに合わせて変更する方法を理解しようとしています。私が知る限り、これは 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

しかし、すべてのラムダに頭を包むことはできません。

4

2 に答える 2

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 親 ID txt rect フラグ セット t 小道具 戻り値 t)))

次のようなラムダ\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

これは流れをたどるのに十分明確ですか?initialWindowと自体を理解しようとはしていinitialTextません。

于 2012-11-17T23:38:14.747 に答える
2

Haskell では、すべてがネストされたラムダです! \txt -> \props flags -> do {...}は と同じですが\txt props flags -> do {...}、どちらも実際には の短縮形です

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

ここで少し紛らわしいのは、\txt props flags多くの議論のように見えることです:

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

は 2 引数の関数を取るように見えますが、それに 3 つのパラメーターのラムダを与えます。しかし覚えておいてください:実際には、すべての関数は1 つの引数しか取りません。それ以外はすべてカリー化によって行われます。この場合aも関数型なので、実際にはむしろ

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

楽しみはそれだけではありません。への引数は、4 ではなく 2という小さなinitialWindowパラメータしか持たないように見えますが、そうではありません: 最初の引数だけを指定しただけで、結果は最初の引数を受け入れる関数になります(この場合、のサイン)。次に、 を返します。これを;として書き直しました。この場合、必要なのはです。initialWindow[Prop w][Prop(Window w)]initialWindowab->cinitialWindowStyle -> a

したがって、initialTextこのアプリケーションでの実際の署名は次のようになります。

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