2

ある信号を別の信号に基づいてパラメータ化するにはどうすればよいですか? たとえば、マウスの x 位置に基づいて fps を変更したいとします。タイプは次のとおりです。

Mouse.x : Signal Int
fps     : number -> Signal Time

この疑似コードの行に沿って Elm に何かを理解させるにはどうすればよいでしょうか。

fps (Mouse.x) : Signal Time

明らかに、liftこの場合は機能しません。結果は次のようになると思いますSignal (Signal Time)(しかし、私はまだ Elm に慣れていません)。

ありがとう!

4

2 に答える 2

4

前文

fps Mouse.x

fps にはIntではなくが必要であるという型エラーが発生しますSignal Int

lift fps Mouse.x : Signal (Signal Int)

あなたはそこで正しいです。CheatXの回答が言及しているように、Elmでこれらの「ネストされたシグナル」を使用することはできません。

ご質問への回答

Standard Librariesにまだ存在しないものを求めているようです。私があなたの質問を正しく理解していれば、タイミングを動的に変更できる時間 (または fps) 信号が必要です。何かのようなもの:

dynamicFps : Signal Int -> Signal Time

のような組み込み関数を使用してもlift、 type の関数からそのような関数を自分で作成することはできませんInt -> Signal Time

ここには3つのオプションがあると思います:

  1. この関数をメーリング リストの Time ライブラリに追加するよう依頼してください。(機能リクエストの手順は、そのような機能のリクエストに対して少し肥大化しているため、該当しないものはスキップできます)
  2. ポートを使用して Elm に接続し、Elm内または JavaScript で問題を回避します。
  3. Time動的に変化する信号を必要としない方法を見つけてください。

オプション1をお勧めします。オプション 3 は残念です。Elm で要求したことができるはずです。Elm を初めて使用する場合、オプション 2 はお勧めできません。オプション 1 はたいした作業ではありません。

オプション 2 について詳しく説明するには、次のようにします。

  1. の送信ポートSignal Intと受信ポートを指定するとSignal Time、JavaScript で独自の動的時間関数を記述できます。http://elm-lang.org/learn/Ports.elmを参照してください。
  2. これを Elm 内から実行したい場合は、より醜いハックが必要になります:

    dynamicFps frames = 
      let start = (0,0)
          time  = every millisecond -- this strains your program enormously
          input = (,) <~ frames ~ time
          step (frameTime,now) (oldDelta,old) = 
            let delta = now - old
            in if (oldDelta,old) == (0,0)
                 then (frameTime,now) -- this is to skip the (0,0) start
                 else if delta * frameTime >= second
                        then (delta,now)
                        else (0,old)
      in dropIf ((==) 0) 0 <| fst <~ foldp step start input
    

    基本的には、絶対的なタイムスタンプを記憶し、できるだけ早く新しい時間を求め、記憶された時間と現在の間の時間が必要な時間枠に十分収まるかどうかを確認します。その場合は、その時間デルタ (fps は時間デルタを提供します) を送信し、新しいタイムスタンプとして記憶します。foldp は覚えておくべきすべてのものを送信するので、新しいデルタと新しい時間の両方を取得します。したがって、使用fst <~するとデルタのみが保持されます。しかし、入力時間は(おそらく)必要な時間枠よりもはるかに速いため、(0,old)から多くの情報を取得できますfoldp。があるのはそのためdropIf ((==) 0)です。

于 2014-07-02T08:34:05.667 に答える
0

ネストされたシグナルは、Elm の型システム [このペーパーのパート 3.2 ] によって明示的に禁止されています。

私が FRP を理解している限り、ネストされたシグナルは、ある種のお世辞が提供されている場合にのみ役立ちます (たとえば、モナドの「結合」関数)。そして、信号履歴全体を保持しないと、その操作を実装するのは困難です。

于 2014-07-01T15:30:53.000 に答える