コンテンツにスキップ

Chapter 1: FRP is like Spreadsheet

Another familiar example of something fundamentally designed to keep its versions perfectly synchronized is the spreadsheet.

And the FRP library being introduced here, Timeline , will be easier to understand if this spreadsheet principle is kept in mind.

Timeline provides binary operations to utilize the state management

Section titled “Timeline provides binary operations to utilize the state management”

In Functional Programming, everything is an expression or operation. Accordingly, Timeline library provides binary operations for the reactive state management .

This binary operation corresponds to an operation in spreadsheet apps.

image

image



'a -> Timeline<'a>
let counter = Timeline 0

Consider the Timeline as a specific container for a value, similar to a Cell in spreadsheet apps.

image


('a -> 'b) -> (Timeline<'a> -> Timeline<'b>)
('a -> Timeline<'b>) -> (Timeline<'a> -> Timeline<'b>)

When the binary operator: is TL.map,

let double = fun a -> a * 2
let timelineA = Timeline 1
let timelineB =
timelineA |> TL.map double
log (timelineB |> TL.at Now)
// 2

This code for the binary operation simply corresponds to the basic usage of spreadsheet apps

image

This is the identical structure of:

let double = a => a * 2;
let listA = [1];
let listB =
listA.map(double);
console.log(listB);
// [2]

image

We could recognize the array [2] is identical to the Cell and Value 2 of a spreadsheet; however, the spreadsheet and Timeline maintain a double relationship as values change over the timeline .


'a -> Timeline<'a> -> unit
let timelineA = Timeline 1
timelineA |> TL.next 3
log (timelineA |> TL.at Now)
// 3

image


The update to timelineA will trigger a reactive update of timelineB according to the rule defined by the binary operation.

image

let double = fun a -> a * 2
// ① initialize timelineA
let timelineA = Timeline 1
// confirm the lastVal of timelineA
log (timelineA |> TL.at Now)
// 1
// ② the binary operation
let timelineB =
timelineA |> TL.map double
// confirm the lastVal of timelineB
log (timelineB |> TL.at Now)
// 2
//=====================================
// ③ update the lastVal of timelineA
timelineA
|> TL.next 3
// update to timelineA will trigger
// a reactive update of timelineB
// confirm the lastVal of timelineA & timelineB
log (timelineA |> TL.at Now)
// 3
log (timelineB |> TL.at Now)
// 6