| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
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 ( ) )Prueba jsfiddle
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 ()]
|> ignoreManifestación
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 ) ; El proyecto VANFS incluye algún código TypeScript.
https://github.com/ken-okabe/vanfs/blob/main/van-api/ts/basic.ts
Código TS con el propósito de conversión utilizando el proxy JS:
// unary function ([a,b,c,...]) in F#
// -> n-ary function (a,b,c,...) in VanJS Esto está bajo el directorio van-api , que es esencial y no quisiéramos modificarlo para que las cosas funcionen.
Los usuarios deben instalar cualquier CSS o componentes web requeridos.
VanJS no proporciona el soporte de instalación específico Beause, es solo un Vanillajs.
Por otro lado, VanFS aclara el proceso paso a paso como se muestra a continuación:
Todo lo que necesitamos para personalizar o importar se encuentra en el directorio web-Imports.
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"
] ;De todos modos, todo el código requerido dentro del proyecto VANFS se compila en un solo paquete de Vanillajs usando Fable y Vite.
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 ;
} ;En TypeScript, en comparación con JavaScript heredado, se requiere un paso adicional para agregar firmas de tipo a todas las variables, funciones y parámetros. Esto a menudo es abrumador.
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 ]
timelineBEl código F# es mucho más limpio y más legible que el código TypeScript.
En f#, rara vez necesitamos agregar tipos manualmente gracias a su poderosa inferencia de tipo. Esto hace que el desarrollo de F# se sienta similar a la codificación Legacy JavaScript.
En realidad, es mucho más que eso.
Si bien los programadores pueden querer definir tipos de objetos fundamentales que formen la columna vertebral de su código, en otros lugares, si el compilador F# advierte por una demanda de anotaciones de tipo manual, por lo general, algo está mal .
En f#, si el compilador no puede inferir el tipo, a menudo sugiere que puede haber inconsistencias matemáticas.
En TypeScript, si el compilador no puede inferir el tipo, a menudo sugiere limitaciones en sus capacidades de inferencia de tipo. Esto hace que sea difícil determinar la causa precisa del problema.
Como resultado, los programadores F# son naturalmente llevados a escribir un código matemáticamente consistente y riguroso; Desafortunadamente, este beneficio rara vez ocurre en TypeScript.
F# generalmente se reconoce como ejecutándose en .NET Framework, pero al igual que TypeScript se compila en JavaScript, F# también se compila en JavaScript.
TypeScript -> JavaScript
F# -> JavaScript
Más precisamente,
Typescirpt
⬇ Compilador TypeScript que se ejecuta en Node.js (npx tsc)
JavaScript ejecutándose en el navegador
F#
⬇ Compilador de fábulas que se ejecuta en .NET (dotnet fable)
JavaScript ejecutándose en el navegador
Por lo tanto, la columna vertebral de VANFS es fábula.
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
.NET SDK
Node.js y NPM CLI o alternativas (Bun / Deno / Yarn, etc.)
Si es nuevo en F# y usa VScode, lea la configuración de F# en VScode.
Un proyecto VANFS/Fable es un híbrido del proyecto F#.NET y el proyecto NPM .
Ver Fable Configuración de documentos
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;
}Manifestación
https://codepen.io/kentechgeek/pen/zyxqyxz
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
VANFS puede aprovechar las etiquetas HTML personalizadas proporcionadas por componentes web con sistemas de diseño : Microsoft Fluent, diseño de material de Google, etc.
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 ()]
|> ignoreCuando se realizan cambios importantes, a veces es necesario limpiar el proyecto Fable.
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 buildManifestación
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"
] ;| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
VanFS se describe como
Enlace 1: 1 de F# a VanJS (un pequeño marco de interfaz de usuario reactivo sin React/JSX) + WebComponents + Micro FRP
o
VANFS es una plantilla de proyecto F# para enlaces directos individuales de VANJS
Los enlaces 1: 1 son absolutamente cierto dentro del alcance de las características básicas para componer UI, pero no un caso para su gestión estatal.
VANJS se une reactivamente a sus objetos de estado a los elementos DOM correspondientes. Esto significa que cuando un objeto de estado se actualiza, el elemento DOM correspondiente también se actualiza automáticamente. Este enfoque es una característica común entre las bibliotecas de UI declarativas como React, Solidjs, etc.
Esta es la estructura idéntica de:
Entonces, esto es FRP.
La programación reactiva funcional (FRP) es un paradigma de programación que utiliza expresiones matemáticas, específicamente operaciones binarias , como un medio para implementar la programación reactiva .
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
Timeline es una biblioteca FRP fundamentalmente independiente, sin dependencias en las características asíncronas de VANJ o F# . La base de código es una implementación de función pura compacta de aproximadamente 30-40 líneas de código.
Timeline<'a>record Timeline < 'a >
val mutable lastVal : 'a
val el : StateElement < 'a >| Campo | Descripción | Estatal |
|---|---|---|
lastVal | Último valor de la línea de tiempo | State.val |
el | Elemento DOM reactivo de la línea de tiempo | 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 Considere la Timeline como un contenedor específico para un valor, similar a una celda en aplicaciones de hoja de cálculo.
let double = fun a -> a * 2
let timelineA = Timeline 1
let timelineB =
timelineA |> mapT double
console.log timelineB.lastVal
// 2Este código para la operación binaria simplemente corresponde al uso básico de las aplicaciones de la hoja de cálculo
Esta es la estructura idéntica de:
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] Podríamos reconocer que la matriz [2] es idéntica a la celda y el valor 2 de una hoja de cálculo; Sin embargo, la hoja de cálculo y la línea de tiempo mantienen una relación double a medida que los valores cambian en la línea de tiempo .
Timeline<'a> nextT'a -> Timeline < 'a > -> Timeline < 'a > let timelineA ' =
timelineA |> nextT 3 O, en la mayoría de los casos, no necesitamos otro timelineA' y queremos descartarlo, así que simplemente ignore el valor devuelto.
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 ()]
|> ignoreManifestación
https://codepen.io/kentechgeek/pen/goyqnqb?editors=1111
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
Dada la importancia crítica de NULL en el desarrollo moderno de software, he dedicado un artículo separado a explorar sus conceptos y beneficios clave.
Tipos de valor anulables en f#
Un tipo de valor anulable
Nullable<'T>representa cualquier tipo de estructura que también pueda sernull. Esto es útil cuando interactúa con bibliotecas y componentes que pueden optar por representar este tipo de tipos, como enteros, con un valornullpor razones de eficiencia. El tipo subyacente que respalda esta construcción es un sistema.
solo puede representar el tipo struct , qué limitación es problemática.
Uso de tipos de referencia anulables en f#
F#: ¿Cómo convierto la opción <'a> a anulable, también cuando' a puede ser system.string?
Sería bueno si pudiéramos escribir tipos anulables que incluyan tipos de referencia en F#.
F# RFC FS -1060 - Tipos de referencia anulables
let nullable1 =
Null
let nullable2 =
NullableT " hello "
log nullable1
// Null
log nullable2
// T hello
log nullable2.Value
// hello Esta especificación se asemeja a los tipos de valor anulable nativo de F#, pero a diferencia de ella, NullableT también puede representar cualquier tipo de referencia.
¡El soporte de nulo f# puede llegar pronto!
Una vista previa del trabajo que se realiza en el compilador F# para admitir las capacidades de nulidad de .NET.
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
Al utilizar el tipo anulable , podemos proporcionar nuevos operadores que combinen la línea de tiempo .
Inicializando una línea de tiempo con valor Null , la función proporcionada permanece sin ejecución y espera en un estado pendiente. Una vez que el valor de la línea de tiempo se actualiza a un valor no Null mediante un evento válido, la función se activa y ejecuta.
Timeline<NullableT<'a>>TimelineNullableT < 'a > -> Timeline < NullableT < 'a >> let timelineNullable = Timeline Null
log timelineNullable.lastVal // use `log` of Timeline
// NullConsidere esta línea de tiempo como una celda vacía en aplicaciones de hoja de cálculo.
Tipo de Timeline y la función:
① Función para inicializar Timeline<'a>
① Función para inicializar Timeline<NullableT<'a>>
es la misma entidad .
Considere Timeline puede aceptar cualquier tipo genérico de 'a que incluya NullableT<'a> .
Por otro lado, en el caso de Timeline<NullableT<'a>> donde el valor del parámetro es un tipo anulable, si necesitamos el comportamiento Timeline para ignorar la función proporcionada y simplemente pasar por el valor Null cuando el parámetro es Null , podemos usar operadores específicos como se muestra a continuación.
mapTN ( NullableT < 'a > -> NullableT < 'b >) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>)bindTN ( NullableT < 'a > -> Timeline < NullableT < 'b >>) -> ( Timeline < NullableT < 'a >> -> Timeline < NullableT < 'b >>) Cuando el operador binario: 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
// NullEste código para la operación binaria simplemente corresponde al uso básico de aplicaciones de hoja de cálculo.
let timelineA ' =
timelineA |> nextTN ( NullableT 3 ) O, en la mayoría de los casos, no necesitamos otro timelineA' y queremos descartarlo, así que simplemente ignore el valor devuelto.
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 ()]
|> ignoreManifestación
https://codepen.io/kentechgeek/pen/wvznvzj?editors=1111
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
Si bien los operadores anulables de Timeline ofrecen un principio básico similar a la promesa de JavaScript, no son capaces de administrar el encadenamiento de tareas, como Promie.
Basado en la línea de tiempo anulable , podemos obtener una tarea de línea de tiempo que es capaz de encadenar tareas.
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| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
taskConcat o (+>) ( 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 ()]
|> ignoreManifestación
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
Manifestación
https://codepen.io/kentechgeek/pen/baeeyvl?editors=1111
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
taskOr o (+|) ( 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
Manifestación
https://codepen.io/kentechgeek/pen/zyxqgwq?editors=1111
| Contenido |
|---|
| ? Holgazanería Versatilidad de la tecnología web Para el desarrollo de aplicaciones de plataforma cruzada |
| Empezando |
| Componentes web |
| ⚡️ Programación reactiva funcional (FRP) ¿Qué es la programación funcional? ¿Cómo se conduce el código de programación funcional? |
| ⏱️ Línea de tiempo |
| ⏱️ Tipos anulables ¿Qué es los tipos de opciones nulos, anulables y de opciones? |
| ⏱️ Timeline Nullable |
| Tarea de línea de tiempo ⏱️ |
| ⏱️ Tarea de línea de tiempo Concat |
| ⏱️ Tarea de línea de tiempo o |
| ⏱️ Tarea de línea de tiempo y |
| Discusiones |
taskAnd y (+&) ( 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
Manifestación
https://codepen.io/kentechgeek/pen/pobmjzq?editors=1111