スプレッドシートのようなものを実装することに興味がある場合は、役立つ可能性があることが 2 つあります。
まず、Cellz プロジェクトは、F# でのスプレッドシートのサンプル実装です。「=SUM(A1:A10)」のような文字列の単純なパーサーが含まれており、これらの文字列から式ツリーを構築します (これは 1 回だけ行われます)。次に、式の値を計算するエバリュエーターも含まれています。
次に、Luca Bolognese が「Eden」と呼ばれる計算フレームワークの実装についていくつか話しました。このフレームワークでは、セルの観点から計算を記述し、セルの値が変更されると、変更が自動的に反映されます (依存セルのみが再計算されます)。彼はTechMesh London 2012で講演する予定ですが、これはどこかに記録されていると思います (しかし見つかりません)。
Eden の背後にある基本的な考え方は、セルは現在の値と、値が変化したときにトリガーされるイベントを持つものとして表されるということです。
type Cell<'T> =
abstract Value : 'T
abstract Changed : IEvent<unit>
明示的に作成および変更されたセルは変更可能Value
であり、値がユーザーによって変更されたときにイベントをトリガーします。
type MutableCell<'T>(value:'T) =
let mutable currentValue = value
let event = Event<unit>()
member x.Value
with get() = currentValue
and set(v) =
currentValue <- v
event.Trigger()
interface Cell<'T> with
member x.Value = currentValue
member x.Changed = event.Publish
次に、何らかの計算の結果として生成されるセルを構築することもできます。これは講演またはブログ投稿のトピックであり、SO の回答ではありませんが、セル内の値を別のセルにマップする単純な変換は次のようになります。
let map f (cell:Cell<_>) =
let currentValue = ref (f cell.Value)
cell.Changed.Add(fun () -> currentValue := f cell.Value)
{ new Cell<_> with
member x.Value = currentValue.Value
member x.Changed = cell.Changed }
複数のセルなどの値を組み合わせることができる必要があります。