5

しばらくの間、FRP に挑戦したいと思っていましたが、昨日ついに弾丸をかじり、Netwire 5 を使用して始めました (それ自体はかなり恣意的な選択ですが、どこかから始めなければなりません!)。「機能するコード」のポイントに到達することができましたが、ライブラリがどのように使用されると予想されるか、またはそれらが私の症状であるかどうか確信が持てないパターンがいくつかあることに気付きました。私はどこかで何か間違ったことをしています。

私はこのチュートリアルから始めました。これは、非常に簡単に起動して実行するのに十分でした-単純な「増分番号」ワイヤで制御される回転する立方体ができました。

spin :: (HasTime t s, Monad m) => Wire s e m a GL.GLfloat
spin = integral 0 . 5

「Esc」が押されるとアプリケーションは終了し、netwire-input-glfwで提供されたワイヤを使用します:

shouldQuit :: (Monoid e, Functor m, Monad m) => Wire s e (GLFWInputT m) a a
shouldQuit = keyPressed GLFW.Key'Escape

これらの重要な違いは、spin常に抑制している間、常に何らかの値を返す必要があるということshouldQuitです。キーが実際に押されるまで、その場合はアプリケーションを終了します。

私を不安にさせるのは、これらのワイヤーを使用しなければならない方法です. 現在、次のようになっています。

(wt', spinWire') <- stepWire spinWire st $ Right undefined
((qt', quitWire'), inp'') <- runStateT (stepWire quitWire st $ Right undefined) inp'

case (qt', wt') of
  (Right _, _) -> return ()
  (_, Left _)  -> return () -- ???
  (_, Right x) -> --do things, render, recurse into next frame

このパターンについて私が不快に感じる点が 2 つあります。Right undefinedまず、への両方の呼び出しに渡すという事実stepWire。(私の理解が正しければ)このパラメータはイベントをワイヤに送信するためのものであり、ワイヤはイベントをまったく使用しないため、これは「安全」ですが、気分が悪いと思います(EDIT多分「イベント」はここで間違った言葉 - チュートリアルはそれを「値をブロックする」と説明していますが、要点はまだ立っています - 私は決してブロックするつもりはなくe、ワイヤーのどこでもパラメーターを使用しません)。stepWireイベントがないことがわかっていて、イベントがあったとしてもそれに応答しないことがわかっているが、イベントが表示されないという状況のバージョンがあるかどうかを確認しました.e()Right ()これは よりわずかに汚れていないように感じますがundefined、それでも私の意図を完全には表していないようです。

同様に、戻り値もEither. これはワイヤに最適ですが、ワイヤの出力でshouldQuitパターン マッチを行う必要があることに注意してください。それが阻害することが何を意味するのか本当にわからないので、ただ、ワイヤの数が増えるにつれてこれが扱いにくくなることは想像できます。決して抑制されず、次の値を保持するために常に信頼できるワイヤーを持っています。wt'spinreturn ()

したがって、動作するコードはあるのですが、どういうわけか「やり方が間違っている」という不安な気持ちが残ります。また、Netwire 5 はかなり新しいため、チェックできる「慣用的な」コードの例を見つけるのは困難です。私がマークの近くにいるかどうか見てください。これはライブラリの使用方法ですか、それとも何か不足していますか?

EDIT :私が言及した 2 番目の問題 ( のEither結果に対するパターン マッチング) は、とを 1 つにspin結合することで解決できました。spinshouldQuitWire

shouldContinuePlaying :: (Monoid e, Functor m, Monad m) => Wire s e (GLFWInputT m) a a
shouldContinuePlaying = keyNotPressed GLFW.Key'Escape

game :: (HasTime t s, Monoid e, Functor m, Monad m) => Wire s e (GLFWInputT m) a GL.GLfloat
game = spin . shouldContinuePlaying

このワイヤをステップ実行すると、はるかに賢明な戻り値が得られますLeft。終了できる場合は終了できますが、そうでない場合は、処理するデータの一部があります。また、私の元の方法よりも構成可能性が高いことも示唆しています。

Right undefinedただし、この新しいワイヤへの入力として渡す必要があります。確かに、現在は 1 つしかありませんが、これが正しいアプローチであるかどうかはまだわかりません。

4

1 に答える 1