3

私は Elm にかなり慣れていないのですが、Elm が GUI を扱う方法に深く惹かれています。しかし、深く考えた結果、Signal の下にあるリストまたは finger ツリー (Elm のライブラリに既に存在する場合、Haskell の finger ツリーのように) の 1 つの要素だけを効率的に更新するのは困難であり、そのサイズもさまざまであることがわかりました。時間に対して。

具体的には、動的な指の木を表現するには、

Signal [ {-指の木の要素型-} ]

しかし、finger ツリーの 1 つの要素だけを効率的に更新したい場合は、次のように記述する必要があります。

シグナル [ シグナル {-コア データ型-} ]

しかし、Elm ではシグナルはモナドではありません。2 つのレイヤーのシグナルを 1 つのレイヤーにフラット化するにはどうすればよいでしょうか?

コメント 1: この状況で Elm がどのように動作するかは詳しくわかりません。指の木全体を再処理するのは私の推測です。

コメント 2: たとえば、 とマークされたsタイプの信号値と、 とマークされSignal (fingerTree Int)た次の関数がありf、その入力が であるsとしlift (fmap (+1))ますSignal (fingerTree Int) -> Signal (fingerTree Int)。また、s要素が 1 つだけ変更された場合、関数fは のすべての要素に対して (+1) 操作をやり直す必要がありsます。明らかに、それは時間の無駄であり、Elm が不変性を検出するのに十分なほどインテリジェントであるかどうかはわかりません。

4

1 に答える 1

5

TL;DR: ロジック/データ処理を純粋な関数として実装し、それらを持ち上げて信号を変換します。

トリックは、必要なロジックを提供する関数を作成するprocessList : [elementType] -> [elementType]ことです (3 番目の要素が wibbler であるかどうかを確認し、それを wobbler に変更するか、やりたいことは何でも)、次の型を持つリフト関数を使用します。

lift : (a -> b) -> Signal a -> Signal b

を使用してlift processList mySignalThatProducesLists生成されたデータを編集したい。mySignalThatProducesListsprocessList

ここでの主なアイデアは、ロジックとデータ処理を純粋な関数としてエンコードし、lift. ソース信号のデータが更新されるたびに、Elm が自動的に関数を再適用するようなものです。

Haskell でのプログラミングに慣れている場合は、一部の不透明な Time 型Signal aの newtype ラッパー、および. データを編集するのにモナドは必要ありません。Time -> aliftfmap

また、複数の引数を持つ関数を持ち上げるための関数もlift2あります。そのため、Haskell の類推を使用すると、基本的に Applicative ファンクターの機能を備えています。lift3

彼らがモナドを持っていない理由は、それが効率を低下させる実装の詳細を課すからです。そこには、私が見つけていない ArrowApply に相当するものがあるかもしれません (これにより、Monad と同等の表現性が得られます) が、あるかどうかはわかりません。

于 2014-10-25T12:18:04.253 に答える