前文
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つのオプションがあると思います:
- この関数をメーリング リストの Time ライブラリに追加するよう依頼してください。(機能リクエストの手順は、そのような機能のリクエストに対して少し肥大化しているため、該当しないものはスキップできます)
- ポートを使用して Elm に接続し、Elm内または JavaScript で問題を回避します。
Time
動的に変化する信号を必要としない方法を見つけてください。
オプション1をお勧めします。オプション 3 は残念です。Elm で要求したことができるはずです。Elm を初めて使用する場合、オプション 2 はお勧めできません。オプション 1 はたいした作業ではありません。
オプション 2 について詳しく説明するには、次のようにします。
- の送信ポート
Signal Int
と受信ポートを指定するとSignal Time
、JavaScript で独自の動的時間関数を記述できます。http://elm-lang.org/learn/Ports.elmを参照してください。
これを 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)
です。