| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
import van from "vanjs-core"
const { a , p , div , li , ul } = van . tags
// Reusable components can be just pure vanilla JavaScript functions.
// Here we capitalize the first letter to follow React conventions.
const Hello =
( ) =>
div (
p ( "Hello" ) ,
ul (
li ( "?️World" ) ,
li ( a ( { href : "https://vanjs.org/" } , "?VanJS" ) ) ,
) ,
)
van . add ( document . body , Hello ( ) )Probieren Sie JSFiddle an
module HelloApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let a : Tag = tags?a
let p : Tag = tags?p
let div : Tag = tags?div
let ul : Tag = tags?ul
let li : Tag = tags?li
let Hello =
fun _ ->
div [
p [ " Hello " ]
ul [
li [ " ?️World " ]
li [ a [{| href = " https://vanjs.org/ " |}; " ?VanJS " ]]
]
]
add [ document.body ; Hello ()]
|> ignoreDemo
https://codepen.io/kentechgeek/pen/vwnovox
let Greeting : Tag =
fun list ->
let name : string = list [ 0 ]? name
div [ $ " Hello {name}! " ]
add [ document.body ; Greeting [{| name = " Ken " |}]]
|> ignore const Greeting : Component < { name : string } > =
( { name } ) =>
< div > Hello { name } ! </ div > ;
render ( ( ) => < Greeting name = "Ken" /> , document . body ) ; Das VANFS -Projekt enthält einen TypeScript -Code.
https://github.com/ken-okabe/vanfs/blob/main/van-api/ts/basic.ts
TS -Code zum Konvertieren mit JS -Proxy:
// unary function ([a,b,c,...]) in F#
// -> n-ary function (a,b,c,...) in VanJS Dies steht unter dem van-api -Verzeichnis, das unerlässlich ist, und wir möchten es nicht ändern, um die Dinge zum Laufen zu halten.
Benutzer müssen alle erforderlichen CSS oder Webkomponenten installieren.
VANJS bietet nicht die spezifische Installationsunterstützung Beauuse, es ist nur ein Vanillejs.
Andererseits verdeutlicht VanFs den schrittweisen Prozess wie unten:
Alles, was wir anpassen oder importieren müssen, befindet sich im Web-Import-Verzeichnis.
import {
provideFluentDesignSystem ,
fluentCard ,
fluentCheckbox
} from "@fluentui/web-components" ;
provideFluentDesignSystem ( )
. register (
fluentCard ( )
) ;
provideFluentDesignSystem ( )
. register (
fluentCheckbox ( )
) ; export let cssURLs = [
"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200"
] ;Unabhängig davon wird der gesamte erforderliche Code innerhalb des VANFS -Projekts mit Fabel und Vite in ein einzelnes VanillaJS -Bundle zusammengestellt.
let bindT = < A , B >
( monadf : ( a : A ) => Timeline < B > ) =>
( timelineA : Timeline < A > ) : Timeline < B > => {
let timelineB = monadf ( timelineA . lastVal ) ;
let newFn = ( a : A ) => {
nextT ( monadf ( a ) . lastVal ) ( timelineB ) ;
return undefined ;
} ;
timelineA . lastFns = timelineA . lastFns . concat ( [ newFn ] ) ;
return timelineB ;
} ;In TypeScript ist im Vergleich zu Legacy JavaScript ein zusätzlicher Schritt erforderlich, um alle Variablen, Funktionen und Parameter zu Typsignaturen hinzuzufügen. Dies ist oft überwältigend.
let bindT =
fun monadf timelineA ->
let timelineB = timelineA.lastVal |> monadf
let newFn =
fun a ->
timelineB
|> nextT ( a |> monadf ) .lastVal
|> ignore
timelineA.lastFns <- timelineA.lastFns @ [ newFn ]
timelineBDer F# Code ist viel sauberer und lesbarer als TypeScript -Code.
In F#müssen wir dank seiner leistungsstarken Inferenz selten manuell addieren. Dadurch fühlt sich die Entwicklung von F# dem Legacy JavaScript -Codieren ähnlich an.
In Wirklichkeit ist es viel mehr als das.
Während Programmierer möglicherweise grundlegende Objekttypen definieren möchten, die das Rückgrat ihres Code bilden, an anderen Stellen, wenn der F# Compiler vor einer Nachfrage von manuellen Annotationen warnt, stimmt normalerweise etwas falsch .
Wenn der Compiler in F#den Typ nicht schließen kann, deutet er häufig darauf hin, dass es mathematische Inkonsistenzen geben kann.
Wenn der Compiler in TypeScript den Typ nicht schließen kann, schlägt er häufig Einschränkungen seiner Typinferenzfunktionen vor. Dies macht es schwierig, die genaue Ursache des Problems zu bestimmen.
Infolgedessen werden F# Programmierer natürlich dazu gebracht, mathematisch konsistenten und strengen Code zu schreiben. Leider geschieht dieser Nutzen in Typenkripten selten .
F# wird allgemein als im .NET -Framework ausgeführt, aber genau wie Typscript mit JavaScript zusammengestellt wird, wird F# auch mit JavaScript zusammengestellt.
TypeScript -> JavaScript
F# -> JavaScript
Genauer gesagt,
TypeScirpt
⬇ Typenkript -Compiler, der auf node.js (npx tsc) ausgeführt wird
JavaScript im Browser läuft
F#
⬇ Fabel Compiler, der auf .NET ausgeführt wird (dotnet fable)
JavaScript im Browser läuft
Daher ist das Rückgrat von VanFs Fabel.
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
.NET SDK
Node.js und NPM CLI oder Alternativen (Bun / Deno / Garn usw.)
Wenn Sie bei F# neu sind und VSCODE verwenden, lesen Sie F# Einstellungen auf VSCODE.
Ein VANFs/Fable -Projekt ist ein Hybrid des F#.NET -Projekts und des NPM -Projekts .
Siehe Fable Setup Documentaion
git clone https://github.com/ken-okabe/vanfs
cd vanfs
dotnet restore # .NET project setup
dotnet tool restore
npm i # npm project setup body {
font-family : sans-serif;
padding : 1 em ;
background-color : beige;
}Demo
https://codepen.io/kentechgeek/pen/zyxqyxz
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
VanFs können benutzerdefinierte HTML -Tags nutzen, die von Webkomponenten mit Designsystemen bereitgestellt werden: Microsoft Fluent, Google -Material -Design usw..
import {
provideFluentDesignSystem ,
fluentCard ,
fluentCheckbox
} from "@fluentui/web-components" ;
provideFluentDesignSystem ( )
. register (
fluentCard ( )
) ;
provideFluentDesignSystem ( )
. register (
fluentCheckbox ( )
) ; body {
font-family : sans-serif;
padding : 1 em ;
background-color : beige;
}
. custom {
--card-width : 200 px ;
--card-height : 150 px ;
padding : 22 px ;
}Program.fs module WebComponentsApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let br : Tag = tags?br
// Define the fluent-card and fluent-checkbox tags
let fluentCard : Tag = tags? `` fluent-card ``
let fluentCheckbox : Tag = tags? `` fluent-checkbox ``
let List =
fun _ ->
fluentCard [
{| `` class `` = " custom " |}
// class is a reserved word in F#
// so we use backticks to escape it
fluentCheckbox [ " Did you check this? " ]
br []
fluentCheckbox [{| `` checked `` = true ; disabled = true |}; " Is this disabled? " ]
br []
fluentCheckbox [{| `` checked `` = true |}; " Checked by default? " ]
]
add [ document.body ; List ()]
|> ignoreWenn größere Änderungen vorgenommen werden, ist das Reinigen des Fable -Projekts manchmal erforderlich.
dotnet fable clean
dotnet fable watchnpx vite import '@material/web/textfield/filled-text-field.js' ;
import '@material/web/button/text-button.js' ;
import '@material/web/button/outlined-button.js' ; . custom3 {
--card-width : 460 px ;
--card-height : 150 px ;
padding : 20 px ;
}
. row {
align-items : flex-start;
display : flex;
flex-wrap : wrap;
gap : 16 px ;
}
. buttons {
justify-content : flex-end;
padding : 16 px ;
}
md-filled-text-field ,
md-outlined-text-field {
width : 200 px ;
} module MaterialUI
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
let div : Tag = tags?div
let form : Tag = tags?form
let fluentCard : Tag = tags? `` fluent-card ``
let mdFilledTextField : Tag = tags? `` md-filled-text-field ``
let mdTextButton : Tag = tags? `` md-text-button ``
let mdOutlinedButton : Tag = tags? `` md-outlined-button ``
let Form =
fun _ ->
fluentCard [
{| `` class `` = " custom3 " |}
form [
div [
{| `` class `` = " row " |}
mdFilledTextField [
{|
label = " First name "
name = " first-name "
required = " "
autocomplete = " given-name "
|}
]
mdFilledTextField [
{|
label = " Last name "
name = " last-name "
required = " "
autocomplete = " family-name "
|}
]
]
div [
{| `` class `` = " row buttons " |}
mdTextButton [
{| `` type `` = " reset " |}
" Reset "
]
mdOutlinedButton [
{| `` type `` = " submit " |}
" Submit "
]
]
]
]
add [ document.body ; Form ()]
|> ignorenpx vite buildDemo
https://codepen.io/kentechgeek/pen/kkylwgn?editors=1111
import '@material/web/icon/icon.js' ;
import '@material/web/iconbutton/icon-button.js' ; https://m3.material.io/styles/icons/overview
export let cssURLs = [
"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200"
] ;| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
VanFs werden als beschrieben als
1: 1 Bindungen von F# zu VanJs (ein winziges reaktives UI -Framework ohne React/JSX) + WebComponents + Micro FRP
oder
VanFs ist eine F# -Projekt-Vorlage für Einzelbindungen von VanJs
1: 1 Bindungen sind im Rahmen der grundlegenden Merkmale für das Komponieren von UIs absolut wahr, aber kein Fall für das staatliche Management.
VanJs bindet seine Zustandsobjekte reaktiv an entsprechende DOM -Elemente. Dies bedeutet, dass das entsprechende DOM -Element beim Aktualisieren eines Statusobjekts auch automatisch aktualisiert wird. Dieser Ansatz ist ein häufiges Merkmal unter deklarativen UI -Bibliotheken wie React, SolidJs usw.
Dies ist die identische Struktur von:
Das ist also frp.
Die funktionale reaktive Programmierung (FRP) ist ein Programmierparadigma, das mathematische Ausdrücke, insbesondere binäre Operationen , als Mittel zur Implementierung von reaktiven Programmierungen verwendet.
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
Die Zeitachse ist eine grundsätzlich eigenständige FRP -Bibliothek ohne Abhängigkeiten von VANJs oder F# Asynchronen Merkmalen. Die Codebasis ist eine kompakte Pure-Funktion-Implementierung von ca. 30-40 Codezeilen.
Timeline<'a>record Timeline < 'a >
val mutable lastVal : 'a
val el : StateElement < 'a >| Feld | Beschreibung | Van.state |
|---|---|---|
lastVal | Letzter Wert der Zeitleiste | State.val |
el | Reaktives DOM -Element der Zeitleiste | State |
Timeline<'a>Timeline'a -> Timeline < 'a > let counter = van . state ( 0 ) ;
console . log ( counter . val ) ;
// 0 let counter = Timeline 0
console.log counter.lastVal
// 0 Betrachten Sie die Timeline als einen bestimmten Container für einen Wert, ähnlich einer Zelle in Tabellenkalkulations -Apps.
let double = fun a -> a * 2
let timelineA = Timeline 1
let timelineB =
timelineA |> mapT double
console.log timelineB.lastVal
// 2Dieser Code für den Binärvorgang entspricht einfach der grundlegenden Verwendung von Tabellenkalkulations -Apps
Dies ist die identische Struktur von:
let double = a => a * 2 ;
let arrayA = [ 1 ] ;
let arrayB =
arrayA . map ( double ) ;
console . log ( arrayB ) ;
// [2] let double =
fun a -> a * 2
let listA = [ 1 ]
let listB =
listA |> List.map double
console.log listB
// [2] Wir könnten erkennen, dass das Array [2] mit der Zelle identisch ist und Wert 2 einer Tabelle; Die Tabelle und die Zeitleiste halten jedoch eine double Beziehung bei , wenn sich die Werte über die Zeitachse ändern .
Timeline<'a> nextT'a -> Timeline < 'a > -> Timeline < 'a > let timelineA ' =
timelineA |> nextT 3 Oder in den meisten Fällen brauchen wir keine weitere timelineA' und möchten es wegwerfen. ignore also einfach den zurückgegebenen Wert.
let timelineA = Timeline 1
timelineA
|> nextT 3
|> ignore
console.log timelineA.lastVal
// 3 let double = fun a -> a * 2
// ① initialize timelineA
let timelineA = Timeline 1
// confirm the lastVal of timelineA
console.log timelineA.lastVal
// 1
// ② the binary operation
let timelineB =
timelineA |> mapT double
// confirm the lastVal of timelineB
console.log timelineB.lastVal
// 2
//=====================================
// ③ update the lastVal of timelineA
timelineA
|> nextT 3
|> ignore
// update to timelineA will trigger
// a reactive update of timelineB
// confirm the lastVal of timelineA & timelineB
console.log timelineA.lastVal
// 3
console.log timelineB.lastVal
// 6 import van from "vanjs-core"
const { button , div , h2 } = van . tags
const Counter =
( ) => {
const counter = van . state ( 0 )
van . derive ( ( ) =>
console . log ( `Counter: ${ counter . val } ` ) )
return div (
h2 ( "❤️ " , counter ) ,
button (
{
onclick : ( ) => ++ counter . val
} ,
"?"
) ,
button (
{
onclick : ( ) => -- counter . val
} ,
"?"
) ,
)
}
van . add ( document . body , Counter ( ) ) module CounterApp
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
let div : Tag = tags?div
let h2 : Tag = tags?h2
let icon : Tag = tags? `` md-icon ``
let iconButton : Tag = tags? `` md-icon-button ``
let Counter =
fun _ ->
let counter = Timeline 0 // ① initialize an Timeline
counter // ② the binary operation of the Timeline
|> mapT ( fun value ->
console.log $ " Counter: {value} " )
|> ignore
// ignore the return value of `console.log`
div [
h2 [ " ❤️ " ; counter.el ] // ? `counter.el`
iconButton [ // for Reactive DOM element
{| onclick = fun _ ->
counter // ③ update the Timeline
|> nextT ( counter.lastVal + 1 )
|}
icon [ " thumb_up " ]
]
iconButton [
{| onclick = fun _ ->
counter // ③ update the Timeline
|> nextT ( counter.lastVal - 1 )
|}
icon [ " thumb_down " ]
]
]
add [ document.body ; Counter ()]
|> ignoreDemo
https://codepen.io/kentechgeek/pen/goyqnqb?editors=1111
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
Angesichts der kritischen Bedeutung von NULL in der modernen Softwareentwicklung habe ich einen separaten Artikel für die Erforschung seiner wichtigsten Konzepte und Vorteile gewidmet.
Nullbare Werttypen in F#
Ein nullierbarer Werttyp
Nullable<'T>repräsentiert jeden Strukturart, der auchnullsein könnte. Dies ist hilfreich, wenn Sie mit Bibliotheken und Komponenten interagieren, die sich möglicherweise für diese Art von Typen wie Ganzzahlen darstellen, mit einemnullaus Effizienzgründen. Der zugrunde liegende Typ, der dieses Konstrukt unterstützt, ist system.nullable.
kann nur struct darstellen, welche Einschränkung problematisch ist.
Verwenden nullierbarer Referenztypen in F#
F#: Wie konvertiere ich die Option <'a> in nullierbar, auch wenn' a kann System.String sein?
Es wäre schön, wenn wir nullbare Typen schreiben könnten, einschließlich Referenztypen in F#.
F# RFC FS -1060 - Nullierbare Referenztypen
let nullable1 =
Null
let nullable2 =
NullableT " hello "
log nullable1
// Null
log nullable2
// T hello
log nullable2.Value
// hello Diese Spezifikation ähnelt dem nativen Nullierwerttypen von F#, aber im Gegensatz zu IT kann NullableT auch alle Referenztypen darstellen.
F# Nullness -Unterstützung kann bald kommen!
Eine Vorschau der Arbeiten am F# Compiler, um die Nullheit -Funktionen von .NET zu unterstützen.
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
Durch die Verwendung des nullbaren Typs können wir neue Bediener zur Verfügung stellen, die mit der Zeitleiste kombiniert werden.
Die initialisierung einer Zeitleiste mit Null , die bereitgestellte Funktion bleibt unerkannt und wartet in einem ausstehenden Zustand. Sobald der Timeline -Wert durch ein gültiges Ereignis auf einen Nicht Null aktualisiert wurde, wird die Funktion dann ausgelöst und ausgeführt.
Timeline<NullableT<'a>>TimelineNullableT < 'a > -> Timeline < NullableT < 'a >> let timelineNullable = Timeline Null
log timelineNullable.lastVal // use `log` of Timeline
// NullBetrachten Sie diese Zeitleiste als leere Zelle in Tabellenkalkulations -Apps.
Timeline -Typ und die Funktion:
① Funktion zum Initialisieren von Timeline<'a>
① Funktion zur Initialisierung Timeline<NullableT<'a>>
ist die gleiche Einheit .
Betrachten Sie Timeline können alle generischen Arten von 'a einschließlich NullableT<'a> akzeptieren.
Andererseits, im Fall von Timeline<NullableT<'a>> wobei der Parameterwert ein nullierbarer Typ ist. Wenn wir das Timeline benötigen, um die bereitgestellte Funktion zu ignorieren und einfach den Null zu durchlaufen, wenn der Parameter Null ist, können wir bestimmte Operatoren wie unten gezeigt verwenden.
mapTN ( NullableT < 'a > -> NullableT < 'b >) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>)bindTN ( NullableT < 'a > -> Timeline < NullableT < 'b >>) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>) Wenn der binäre Operator: mapT ,
let double =
fun a -> NullableT ( a * 2 )
// ① initialize timelineA
let timelineA = Timeline Null
log timelineA.lastVal // use `log` of Timeline
// Null
// ② the binary operation
let timelineB =
timelineA |> mapTN double
// currently, `timelineA = Timeline Null`
// so, `double` function is ignored
// and `timelineB` value becomes `Null`
log timelineB.lastVal // use `log` of Timeline
// NullDieser Code für den Binärvorgang entspricht einfach der grundlegenden Verwendung von Tabellenkalkulations -Apps.
let timelineA ' =
timelineA |> nextTN ( NullableT 3 ) Oder in den meisten Fällen brauchen wir keine weitere timelineA' und möchten es wegwerfen. ignore also einfach den zurückgegebenen Wert.
Timeline<'a> let double =
fun a -> NullableT ( a * 2 )
// ① initialize timelineA
let timelineA = Timeline Null
log timelineA.lastVal // use `log` of Timeline
// Null
// ② the binary operation
let timelineB =
timelineA |> mapTN double
// currently, `timelineA = Timeline Null`
// so, `double` function is ignored
// and `timelineB` value becomes `Null`
log timelineB.lastVal // use `log` of Timeline
// Null
// ③ update the lastVal of timelineA
timelineA
|> nextTN ( NullableT 3 )
|> ignore
log timelineA.lastVal // use `log` of Timeline
// T 3
// Now, `timelineA` value is updated to non `Null` value
// Accordingly, `timelineB` reactively becomes `double` of it
log timelineB.lastVal
// T 6 module Number
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
let h4 : Tag = tags?h4
let fluentCard : Tag = tags? `` fluent-card ``
let fluentTextField : Tag = tags? `` fluent-text-field ``
let Number =
fun _ ->
let number = Timeline Null
let numberX2 =
number
|> mapTN ( fun n -> NullableT ( n * 2 )) //System.Nullable
fluentCard [
{| `` class `` = " custom1 " |}
h4 [ " Number " ]
fluentTextField [
{|
appearance = " outline "
required = true
`` type `` = " number "
placeholder = " 1 "
oninput =
fun e ->
let value =
if e?target?value = " "
then Null
else NullableT e?target?value
if value = Null // clear the output textField
then numberX2
|> nextTN Null
|> ignore
document.getElementById ( " output-field " )? value
<- " Null " // clear the output textField
else ()
number
|> nextTN value
|> ignore
|}
]
h4 [ " Number × 2 " ]
fluentTextField [
{|
appearance = " outline "
readonly = true
value = numberX2.el
id = " output-field "
|}
]
]
add [ document.body ; Number ()]
|> ignoreDemo
https://codepen.io/kentechgeek/pen/wvznvzj?editors=1111
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
Während die Timeline Nullierbetreiber ein grundlegendes Prinzip anbieten, das JavaScripts Versprechen ähnelt, können sie nicht in der Lage sein, Aufgaben zu verkürzen, wie z. B. Promie.
Basierend auf dem nullierbaren Timeline können wir eine Zeitleistenaufgabe erhalten, die in der Lage ist, Aufgaben zu verketten.
TaskTimeline < NullableT < 'a >> -> 'b -> unit let task =
fun timelineResult previousResult ->
log " -----------task1 started... "
log previousResult
// delay-------------------------------
let f = fun _ ->
log " .......task1 done "
timelineResult
|> nextTN ( NullableT 1 )
|> ignore
setTimeout f 2000taskTTask < 'a , NullableT < 'a0 >> -> Timeline < NullableT < 'a >> -> Timeline < NullableT < 'a >> let timelineStarter =
Timeline ( NullableT 0 )
// tasks start immediately
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
taskConcat oder (+>) ( Task -> Task ) -> Task let task12 =
task1 +> task2
let task123 =
task1 +> task2 +> task3
let task1234 =
task123 +> task4 module Tasks
open Browser
open Browser. Types
open Fable. Core . JsInterop
open Van. Basic // import tags, add
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskConcat
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let br : Tag = tags? `` br ``
let fluentCard : Tag = tags? `` fluent-card ``
let linerProgress : Tag = tags? `` md-linear-progress ``
let Tasks =
fun _ ->
let progressInit = false
let progressStart = true
let progressDone = false
let percentInit = 0.0
let percentStart = 0.0
let percentDone = 1.0
let timelineProgress1 = Timeline progressInit
let timelineProgress2 = Timeline progressInit
let timelineProgress3 = Timeline progressInit
let timelinePercent1 = Timeline percentInit
let timelinePercent2 = Timeline percentInit
let timelinePercent3 = Timeline percentInit
let taskStart =
fun timelineProgress timelinePercent ->
timelineProgress
|> nextT progressStart
|> ignore
timelinePercent
|> nextT percentStart
|> ignore
let taskDone =
fun timelineProgress timelinePercent timelineResult ->
timelineProgress
|> nextT progressDone
|> ignore
timelinePercent
|> nextT percentDone
|> ignore
timelineResult
|> nextTN ( NullableT 999 )
|> ignore
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
taskStart timelineProgress1 timelinePercent1
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
taskDone timelineProgress1 timelinePercent1 timelineResult
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
taskStart timelineProgress2 timelinePercent2
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
taskDone timelineProgress2 timelinePercent2 timelineResult
setTimeout f 2500
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
taskStart timelineProgress3 timelinePercent3
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
taskDone timelineProgress3 timelinePercent3 timelineResult
setTimeout f 2500
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +>
task2 +>
task3
timelineStarter
|> taskT task123
|> ignore
(* task123 can be written as below
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore
*)
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN ( NullableT 0 )
|> ignore
setTimeout start 2000
fluentCard [
{| `` class `` = " custom2 " |}
br []
linerProgress [
{| indeterminate = timelineProgress1.el
value = timelinePercent1.el |}
]
br []
linerProgress [
{| indeterminate = timelineProgress2.el
value = timelinePercent2.el |}
]
br []
linerProgress [
{| indeterminate = timelineProgress3.el
value = timelinePercent3.el |}
]
]
add [ document.body ; Tasks ()]
|> ignoreDemo
https://codepen.io/kentechgeek/pen/jordjvy?editors=1111
module Tasks
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskConcat
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true // some non-null value
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN nonNull
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +>
task2 +>
task3
timelineStarter
|> taskT task123
|> ignore
(* task123 can be written as below
timelineStarter
|> taskT task1
|> taskT task2
|> taskT task3
|> ignore
*)
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Demo
https://codepen.io/kentechgeek/pen/baeeyvl?editors=1111
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
taskOr oder (+|) ( Task -> Task ) -> Task let task12 =
task1 +| task2
let task123 =
task1 +| task2 +| task3
let task1234 =
task123 +| task4 module TaskOr
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskOr
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN ( NullableT " task1 " )
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN ( NullableT " task2 " )
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN ( NullableT " task3 " )
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +| task2 +| task3
let taskOutput =
fun timelineResult ( previousResult : NullableT < string >)
-> log ( " The fastest result from: "
+ previousResult.Value )
timelineStarter
|> taskT task123 // Run all tasks then return the fastest result
|> taskT taskOutput // log the fastest result
|> ignore
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Demo
https://codepen.io/kentechgeek/pen/zyxqgwq?editors=1111
| Inhalt |
|---|
| ? Vanfs Vielseitigkeit der Web -Technologie Für plattformübergreifende App-Entwicklung |
| Erste Schritte |
| Webkomponenten |
| ⚡️ Funktionelle reaktive Programmierung (FRP) Was ist funktionale Programmierung? Wie fährt funktionaler Programmiercode an? |
| ⏱️ Timeline |
| ⏱️ Nullierstypen Was sind Null-, Nullier- und Optionstypen? |
| ⏱️ Timeline Nullierbar |
| ⏱️ Timeline -Aufgabe |
| ⏱️ Timeline -Aufgabe concat |
| ⏱️ Timeline -Aufgabe oder |
| ⏱️ Timeline -Aufgabe und |
| Diskussionen |
taskAnd oder (+&) ( Task -> Task ) -> Task let task12 =
task1 +& task2
let task123 =
task1 +& task2 +& task3
let task1234 =
task123 +& task4 module TaskAnd
open Van. TimelineElement // import Timeline
open Van. TimelineElementNullable // import Timelinetc.
open Van. Nullable // import NullableT
open Van. TimelineElementTask
open Van. TimelineElementTaskAnd
open System. Timers
let setTimeout f delay =
let timer = new Timer ( float delay )
timer.AutoReset <- false
timer.Elapsed.Add ( fun _ -> f ())
timer.Start ()
let nonNull = NullableT true
let task1 =
fun timelineResult previousResult ->
log " -----------task1 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task1 done "
timelineResult
|> nextTN ( NullableT " task1 " )
|> ignore
setTimeout f 2500
let task2 =
fun timelineResult previousResult ->
log " -----------task2 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task2 done "
timelineResult
|> nextTN ( NullableT " task2 " )
|> ignore
setTimeout f 1000
let task3 =
fun timelineResult previousResult ->
log " -----------task3 started... "
// delay-------------------------------
let f = fun _ ->
log " ...task3 done "
timelineResult
|> nextTN ( NullableT " task3 " )
|> ignore
setTimeout f 3000
let timelineStarter = Timeline Null //tasks disabled initially
let task123 =
task1 +& task2 +& task3
let taskOutput =
fun timelineResult ( previousResult : NullableT < ListResult < 'a >>)
-> log previousResult.Value.results
timelineStarter
|> taskT task123 // Run all tasks then return the list of results
|> taskT taskOutput // log the list of results
|> ignore
let start =
fun _ -> // timeline will start
timelineStarter
|> nextTN nonNull
|> ignore
setTimeout start 2000
Demo
https://codepen.io/kentechgeek/pen/pobmjzq?editors=1111