3

私はUIのFRPの実用的な側面についていくつかの研究を行っており、リアクティブバナナを使用して次の機能を実装するのに苦労しています:選択ボックスの値に基づいて、いくつかの結果を表示する可変量のリストボックスがレンダリングされます. (私は WxHaskell を使用しています。)

結果ビヘイビアーに基づいて非表示および表示される一連の準備済みリスト ボックスを使用してこれを実装するのは非常に簡単でしたが、今回は必要に応じてリスト ボックスを作成および破棄し、各リスト ボックスが結果ビヘイビアーにリンクされるようにします。

これまでのところ、次の成分があります。

  • eParam選択ボックスにバインドされたイベント
  • すべての結果 (リスト ボックスごとの項目のリスト) を保持する(および) でbResults :: Behavior t [[String]]定義された動作eParamstepper
  • updateResultControls :: [SingleListBox ()] -> [[String]] -> IO [SingleListBox ()]結果に基づいてリスト ボックスを破棄または構築する更新関数。戻り値の型が IO であることに注意してください。

BarTabの例を見て、次の実装を試みました。

  • bResultControls :: Behavior t [SingleListBox ()]として定義されるリスト ボックスでの動作stepper [] eUpdateResultControls
  • eUpdateResultControls :: Event t [SingleListBox ()]UI の更新を実行するイベント。bResultControlsこのイベントは、動作とに依存しbResultsます。ただし、ネットワークを更新して IO を実行する必要もあるため、関与する可能性があると思わMomentれます。executeここで行き詰まりました。

私の最新の試みはこれです:

rec
  let
    bResultControls = stepper [] eResultControls
    bResultControlsUpdate = updateResultControls <$> bResultControls <*> bResults

  eResultControls <- execute $ FrameworksMoment . liftIO <$> (bResultControlsUpdate <@ eParam)

しかし、次のタイプのエラーが発生します。

Couldn't match type `m0 [SingleListBox ()]'
              with `forall t1. Frameworks t1 => Moment t1 [SingleListBox ()]'
Expected type: IO [SingleListBox ()]
               -> forall t. Frameworks t => Moment t [SingleListBox ()]
  Actual type: IO [SingleListBox ()] -> m0 [SingleListBox ()]
In the second argument of `(.)', namely `liftIO'
In the first argument of `(<$>)', namely
  `FrameworksMoment . liftIO'
In the second argument of `($)', namely
  `FrameworksMoment . liftIO <$> (bResultControlsUpdate <@ eParam)'

これにはいくつかの動作のトリミングが含まれると思われます。または、おそらくこれについて完全に間違った方法で行っていると思います。

4

1 に答える 1

2

さらに読んで実験した後、慎重にトリミングとリファクタリングを行って動作するようになりました(ハインリッヒが示唆したように):

networkDescription :: forall t. Frameworks t => Moment t ()
networkDescription = do
  eParam <- choiceSelection cParam

  let bResults = results <$> stepper x eParam

  bResults_ <- trimB bResults

  rec
    let
      bResultControls = stepper [] eResultControls

      mkResultControls :: [SingleListBox ()] -> [[String]] -> FrameworksMoment [SingleListBox ()]
      mkResultControls cs rs = FrameworksMoment $ do
        slResults <- liftIO $ updateResultControls cs rs

        bResults <- now bResults_

        sequence_ [sink sl [items :== (!! i) <$> bResults] | sl <- slResults | i <- [0..]]

        liftIO $ do
          let n = length rs
          set f [clientSize := sz (150 * n) 200]
          set pResults [layout := fill $ boxed "results" $ row n (map (fill . widget) slResults)]
          refit f

        return slResults

    eResultControls <- execute $ (mkResultControls <$> stepper [] eResultControls <*> bResults) <@ eParam

  return ()

(動作が更新される前にイベントが発生する小さなバグが発生しましたが、これは簡単に修正できるはずです。)

于 2014-08-06T21:45:41.273 に答える