Elm - Guida rapida
Elm è un linguaggio di programmazione funzionale. È stato progettato da Evan Czaplicki nel 2012.
Elm è utilizzato specificamente per la progettazione del front-end di applicazioni web.
Elm compila in JavaScript e viene eseguito nel browser. È veloce, testabile, gestibile e senza eccezioni di runtime.
Alcune applicazioni pratiche della piattaforma di programmazione Elm includono:
- Games
- Graphics
- Applicazioni a pagina singola
Perché Elm
Elm elimina la maggior parte dei problemi comuni affrontati dagli sviluppatori di frontend. Ciò include:
Nessuna eccezione di runtime
Elm è un linguaggio tipizzato staticamente. Tutti i possibili errori vengono convalidati e corretti in fase di compilazione. Ciò rende possibile non avere eccezioni di runtime.
Messaggi di errore intuitivi per gli sviluppatori
A differenza di altri linguaggi di programmazione, il compilatore di Elm è progettato per fornire messaggi di errore molto specifici e intuitivi per gli sviluppatori in fase di compilazione. I messaggi di errore includono anche suggerimenti come collegamenti a documentazioni di progettazione consigliate.
Facile da testare
Ogni funzione Elm può essere testata separatamente da tutte le altre. Questo rende i programmi scritti in Elm facilmente testabili.
Controllo delle versioni semantico automatico
Elm impone il controllo semantico automatico delle versioni dei pacchetti. Ciò garantisce che una modifica della patch non causi il blocco di un'applicazione già in esecuzione.
Codice riutilizzabile
Le funzioni Elm sono intrinsecamente facili da riutilizzare rispetto alle funzioni in JavaScript, Python o TypeScript.
Questo capitolo descrive i passaggi per installare Elm su piattaforme Windows, Mac e Linux.
Configurazione dell'ambiente locale
Considera i passaggi mostrati di seguito per installare Elm nel tuo ambiente locale.
Step 1 − Install node
Poiché elm è compilato in JavaScript, la macchina di destinazione dovrebbe avere nodeinstallato. Fare riferimento al corso TutorialsPoint NodeJS per la procedura di configurazionenode e npm
Configurazione del nodo.Step 2 − Install elm
Esegui il seguente comando sul terminale per installare elm. Nota che la versione stabile di elm era la 0.18 al momento della stesura di questo corso.
npm install -g [email protected]
Dopo l'installazione, eseguire il seguente comando per verificare la versione di Elm.
C:\Users\dell>elm --version
0.18.0
Step 2 − Install the Editor
L'ambiente di sviluppo utilizzato qui è Visual Studio Code (piattaforma Windows).
Visual Studio Code è un IDE open source di Visual Studio. È disponibile per piattaforme Mac OS X, Linux e Windows. VSCode è disponibile su
Installazione su Windows
In questa sezione, discuteremo i passaggi per installare Elm su Windows.
Scarica
Fare doppio clic su VSCodeSetup.exe per avviare il processo di installazione. Ci vorrà solo un minuto.
Puoi attraversare direttamente il percorso del file facendo clic con il pulsante destro del mouse su File → Apri nel prompt dei comandi. Allo stesso modo, l'opzione Reveal in Explorer mostra il file in File Explorer.
Installazione su Mac OS X
La guida all'installazione specifica per Mac OS X di Visual Studio Code è disponibile all'indirizzo
Installazione su Linux
La guida all'installazione specifica per Linux di Visual Studio Code è disponibile all'indirizzo
Step 4 − Install the elm Extension
Installa l'estensione elm in VSCode come mostrato di seguito.
Elm REPL
REPL sta per Read Eval Print Loop. Rappresenta un ambiente informatico come una console Windows o una shell Unix / Linux in cui viene immesso un comando e il sistema risponde con un output in modalità interattiva.
Elm viene fornito in bundle con un ambiente REPL. Svolge le seguenti attività:
Lettura: legge l'input dell'utente, analizza l'input nella struttura dati di elm e lo archivia in memoria.
Eval - Prende e valuta la struttura dei dati.
Stampa: stampa il risultato.
Loop - Ripete il comando precedente finché l'utente non esce. Utilizzare il comando: esci per uscire da REPL e tornare al terminale.
Di seguito è mostrato un semplice esempio per aggiungere due numeri in REPL:
Apri il terminale VSCode e digita il comando elm REPL.
Il terminale REPL attende che l'utente inserisca un input. Immettere la seguente espressione 10 + 20. L'ambiente REPL elabora l'input come indicato di seguito:
Legge i numeri 10 e 20 dall'utente.
Valuta utilizzando l'operatore +.
Il risultato delle stampe è 30.
Loop per il successivo input dell'utente. Qui usciamo dal loop.
Questo capitolo discute come scrivere un semplice programma in elm.
Step 1 − Create a directory HelloApp in VSCode
Ora crea un file - Hello.elm in questa directory.
Il diagramma sopra mostra la cartella del progetto HelloApp e terminale aperto in VSCode.
Step 2 − Install the necessary elm packages
Il gestore dei pacchetti in elm è elm-package . Installa il pacchetto elm-lang / html . Questo pacchetto ci aiuterà a visualizzare l'output del codice elm nel browser.
Attraversa il HelloApp cartella del progetto facendo clic con il pulsante destro del mouse su File → Apri nel prompt dei comandi in VSCode.
Esegui il seguente comando nella finestra del terminale:
C:\Users\dell\Elm\HelloApp> elm-package install elm-lang/html
I seguenti file / cartelle vengono aggiunti alla directory del progetto durante l'installazione del pacchetto.
- elm-package.json (file), memorizza i metadati del progetto
- elm-stuff (cartella), memorizza i pacchetti esterni
Una volta installato correttamente il pacchetto, verrà visualizzato il seguente messaggio.
Step 3 − Add the following code to the Hello.elm file
-- importing Html module and the function text
import Html exposing (text)
-- create main method
main =
-- invoke text function
text "Hello Elm from TutorialsPoint"
Il programma sopra mostrerà un messaggio di stringa Hello Elm from TutorialsPoint nel browser.
Per questo, dobbiamo importare la funzione text all'interno del Htmlmodulo. La funzione di testo viene utilizzata per stampare qualsiasi valore di stringa nel browser. Il metodo principale è il punto di ingresso a un programma. Il metodo principale richiama la funzione di testo e le passa un valore stringa.
Step 4 − Compile the project
Esegui il seguente comando nella finestra del terminale VSCode.
elm make Hello.elm
L'output del comando precedente è come mostrato di seguito:
//update path to the proj folder in the command elm make
C:\Users\dell\elm\HelloApp>elm make Hello.elm
Success! Compiled 38 modules.
Successfully generated index.html
Il comando precedente genererà un file index.htmlfile. Il compilatore elm converte il file .elm in JavaScript e lo incorpora nel fileindex.html file.
Step 5 − Open the index.html in the browser
Apri il file index.html in qualsiasi browser. L'output sarà come mostrato di seguito -
Commenti in Elm
I commenti sono un modo per migliorare la leggibilità di un programma. I commenti possono essere utilizzati per includere informazioni aggiuntive su un programma come l'autore del codice, suggerimenti su un costrutto di funzione, ecc. I commenti vengono ignorati dal compilatore.
Elm supporta i seguenti tipi di commenti:
Commenti su una sola riga (-) - Qualsiasi testo compreso tra a - e la fine di una riga viene considerato un commento.
Commenti su più righe ({- -}): questi commenti possono estendersi su più righe.
Illustrazione
-- this is single line comment
{- This is a
Multi-line comment
-}
Linee e rientro
Elm non fornisce parentesi graffe per indicare blocchi di codice per definizioni di funzioni o controllo di flusso. I blocchi di codice sono indicati dall'indentazione della riga, che viene applicata in modo rigido. Tutte le istruzioni all'interno di un blocco devono essere rientrate della stessa quantità. Ad esempio:
module ModuleIf exposing (..)
x = 0
function1 =
if x > 5 then
"x is greater"
else
"x is small"
Tuttavia, il blocco seguente genera un errore:
-- Create file ModuleIf.elm
module ModuleIf exposing (..)
x = 0
function1 =
if x > 5 then
"x is greater"
else --Error:else indentation not at same level of if statement
"x is small"
Pertanto, in Elm tutte le linee continue rientrate con lo stesso numero di spazi formerebbero un blocco.
C:\Users\admin>elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at
<https://github.com/elm-lang/elm-repl>
---------------------------------------
-----------------------------------------
> import ModuleIf exposing(..) -- importing module from ModuleIf.elm file
>function1 -- executing function from module
-- SYNTAX PROBLEM ---------------------------------------------------
I need whitespace, but got stuck on what looks like a new declaration.
You are either missing some stuff in the declaration above or just need to add some spaces here:
7| else
^
I am looking for one of the following things:
whitespace
Il Type System rappresenta i diversi tipi di valori supportati dalla lingua. Il Type System verifica la validità dei valori forniti, prima che vengano memorizzati o manipolati dal programma. Ciò garantisce che il codice si comporti come previsto. Il Type System consente inoltre suggerimenti più ricchi sul codice e documentazione automatizzata.
Elm è un linguaggio tipizzato staticamente. Elm ha tipi simili a quelli di altre lingue.
Numero
Il numero tipo di dati rappresenta valori numerici. Il sistema di tipi Elm supporta i seguenti tipi numerici:
Sr. No. | genere | Esempio |
---|---|---|
1 | numero - Memorizza qualsiasi numero | 7 è il tipo di numero |
2 | Float - Memorizza i valori frazionari | 7/2 dà 3.5 come risultato Float |
3 | Int: memorizza valori non frazionari | 7 // 2 restituisce 3 come risultato Int |
Il numero di tipo accetta valori sia frazionari che non frazionari. Apri elm REPL e prova gli esempi riportati di seguito:
C:\Users\admin>elm repl
---- elm-repl 0.18.0
---------------------------------------------
--------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
------------------------------------------
--------------------------------------
> 7
7 : number
> 7/2
3.5 : Float
> 7//2
3 : Int
>
String e Char
Il tipo di dati String viene utilizzato per rappresentare una sequenza di caratteri. Il tipo di dati Char viene utilizzato per rappresentare un singolo carattere. I valori stringa sono definiti tra virgolette doppie "e i valori Char sono racchiusi tra virgolette singole '.
Sr. No. | genere | Esempio |
---|---|---|
1 | Stringa: memorizza una sequenza di caratteri | "TutorialsPoint" |
2 | Char - Memorizza valori frazionari | 'T' |
Apri elm REPL e prova gli esempi riportati di seguito:
C:\Users\admin>elm repl
---- elm-repl 0.18.0 ---------------------------------------
--------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------
------------------------------------------
> "TutorialsPoint"
"TutorialsPoint" : String
> 'T'
'T' : Char
Bool
Il tipo di dati Bool in Elm supporta solo due valori: True e False. La parola chiave Bool viene utilizzata per rappresentare un valore booleano.
Sr. No. | genere | Esempio |
---|---|---|
1 | Bool: memorizza i valori True o False | 1 == 1 restituisce True |
Apri elm REPL e prova gli esempi riportati di seguito:
C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 -----------------------------------
------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
----------------------------------------
----------------------------------------
> True
True : Bool
> False
False : Bool
> 1==1
True : Bool
> 1==2
False : Bool
> 1 /= 2 -- not equal
True : Bool
> not True
False : Bool
> not False
True : Bool
Tipi personalizzati
Elm supporta la creazione di tipi definiti dall'utente. Ad esempio, considera un'applicazione di pagamento. L'applicazione deve memorizzare diverse modalità di pagamento: carta di credito, carta di debito e net banking. Ciò può essere ottenuto definendo un tipo personalizzato e limitandone il valore alle tre modalità di pagamento accettabili.
L'esempio seguente mostra come creare un tipo personalizzato.
> type PaymentMode = CreditCard|NetBanking|DebitCard
> payment1 = CreditCard
CreditCard : Repl.PaymentMode
> payment2 = DebitCard
DebitCard : Repl.PaymentMode
> payment3 = UPI
-- NAMING ERROR ---------------------------------------------- repl-temp-000.elm
Cannot find variable `UPI`
7| payment3 = UPI
Nell'esempio sopra, abbiamo creato un tipo personalizzato PaymentMode. Le variabili payment1 e payment2 vengono assegnate ai valori PaymentMode. Se il valore assegnato alla variabile non corrisponde a nessuno dei valori definiti dal tipo PaymentMode, l'applicazione genererà un errore di sintassi.
Tipi di dati strutturati
I tipi di dati strutturati possono essere utilizzati per memorizzare più valori in un formato strutturato. Elm supporta i seguenti tipi di dati strutturati:
- Tuple
- List
- Record
- Record
Questi saranno discussi in dettaglio nei prossimi capitoli.
Una variabile, per definizione, è "uno spazio con nome nella memoria" che memorizza i valori. In altre parole, funge da contenitore per i valori in un programma. Una variabile aiuta i programmi a memorizzare e manipolare i valori.
Le variabili in Elm sono associate a un tipo di dati specifico. Il tipo di dati determina la dimensione e il layout della memoria della variabile, l'intervallo di valori che possono essere memorizzati all'interno di quella memoria e l'insieme di operazioni che possono essere eseguite sulla variabile.
Regole di denominazione delle variabili
In questa sezione, impareremo le regole di denominazione delle variabili.
- I nomi delle variabili possono essere composti da lettere, cifre e il carattere di sottolineatura.
- I nomi delle variabili non possono iniziare con una cifra. Deve iniziare con una lettera o un trattino basso.
- Le lettere maiuscole e minuscole sono distinte perché Elm fa distinzione tra maiuscole e minuscole.
Dichiarazione delle variabili in Elm
La sintassi del tipo per dichiarare una variabile in Elm è fornita di seguito:
Sintassi 1
variable_name:data_type = value
La sintassi ":" (nota come annotazione di tipo) viene utilizzata per associare la variabile a un tipo di dati.
Sintassi 2
variable_name = value-- no type specified
Il tipo di dati è facoltativo durante la dichiarazione di una variabile in Elm. In questo caso, il tipo di dati della variabile viene dedotto dal valore ad essa assegnato.
Illustrazione
Questo esempio usa l'editor VSCode per scrivere un programma elm ed eseguirlo usando elm repl.
Step 1 − Create a project folder - VariablesApp. Create a Variables.elm file in the project folder.
Aggiungi il seguente contenuto al file.
module Variables exposing (..) //Define a module and expose all contents in the module
message:String -- type annotation
message = "Variables can have types in Elm"
Il programma definisce un modulo Variabili. Il nome di un modulo deve essere lo stesso del file di programma elm. La sintassi (..) viene utilizzata per esporre tutti i componenti nel modulo.
Il programma dichiara un messaggio variabile di tipo String .
Step 2 − Execute the program.
- Digita il seguente comando nel terminale VSCode per aprire elm REPL.
elm repl
- Eseguire la seguente istruzione elm nel terminale REPL.
> import Variables exposing (..) --imports all components from the Variables module
> message --Reads value in the message varaible and prints it to the REPL
"Variables can have types in Elm":String
>
Illustrazione
Usa Elm REPL per provare il seguente esempio.
C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 ---------------------------------------
--------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
-------------------------------------
------------------------------------------
> company = "TutorialsPoint"
"TutorialsPoint" : String
> location = "Hyderabad"
"Hyderabad" : String
> rating = 4.5
4.5 : Float
Qui, le variabili azienda e posizione sono variabili stringa e il rating è una variabile Float.
Il REPL elm non supporta l'annotazione del tipo per le variabili. L'esempio seguente genera un errore se il tipo di dati viene incluso durante la dichiarazione di una variabile.
C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 -----------------------------------------
------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
----------------------------------------
----------------------------------------
> message:String
-- SYNTAX PROBLEM -------------------------------------------- repl-temp-000.elm
A single colon is for type annotations. Maybe you want :: instead? Or maybe you
are defining a type annotation, but there is whitespace before it?
3| message:String
^
Maybe <http://elm-lang.org/docs/syntax> can help you figure it out.
Per inserire un'interruzione di riga durante l'utilizzo di elm REPL, utilizzare la sintassi \ come mostrato di seguito -
C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 --------------------------------------
---------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
------------------------------------------
--------------------------------------
> company \ -- firstLine
| = "TutorialsPoint" -- secondLine
"TutorialsPoint" : String
Un operatore definisce alcune funzioni che verranno eseguite sui dati. I valori su cui lavorano gli operatori sono chiamati operandi. Considera la seguente espressione
7 + 5 = 12
Qui, i valori 7, 5 e 12 sono operandi, mentre + e = sono operatori.
I principali operatori in Elm possono essere classificati come:
- Arithmetic
- Relational
- Logical
Operatori aritmetici
Supponiamo che i valori nelle variabili aeb siano 7 e 2 rispettivamente.
Mostra esempi
Sr. No. | Operatore | Descrizione | Esempio |
---|---|---|---|
1 | + (Aggiunta) | restituisce la somma degli operandi | a + b è 9 |
2 | -(Sottrazione) | restituisce la differenza dei valori | ab è 5 |
3 | * (Moltiplicazione) | restituisce il prodotto dei valori | a * b è 14 |
4 | / (Float Division) | esegue un'operazione di divisione e restituisce un quoziente float | a / b è 3.5 |
5 | // (Divisione intera) | esegue l'operazione di divisione e restituisce un quoziente intero | a // b è 3 |
6 | % (Modulo) | esegue l'operazione di divisione e restituisce il resto | a% b è 1 |
Operatori relazionali
Gli operatori relazionali testano o definiscono il tipo di relazione tra due entità. Questi operatori vengono utilizzati per confrontare due o più valori. Gli operatori relazionali restituiscono un valore booleano, ovvero vero o falso.
Supponiamo che il valore di a sia 10 eb sia 20.
Mostra esempi
Sr. No. | Operatore | Descrizione | Esempio |
---|---|---|---|
1 | > | Più grande di | (a> b) è False |
2 | < | Minore di | (a <b) è vero |
3 | > = | Maggiore o uguale a | (a> = b) è False |
4 | <= | Minore o uguale a | (a <= b) è vero |
5 | == | Uguaglianza | (a == b) è falso |
6 | ! = | Non uguale | (a! = b) è vero |
Tipi comparabili
Operatori di confronto come> = o <funzionano con tipi comparabili. Questi sono definiti come numeri, caratteri, stringhe ed elenchi, tuple. I tipi comparabili su entrambi i lati dell'operatore devono essere gli stessi.
Sr. No. | Tipo comparabile | Esempio |
---|---|---|
1 | numero | 7> 2 dà True |
2 | personaggio | 'a' == 'b' restituisce False |
3 | corda | "ciao" == "ciao" restituisce True |
4 | tupla | (1, "Uno") == (1, "Uno") restituisce True |
5 | elenco | [1,2] == [1,2] restituisce True |
Apri elm REPL e prova gli esempi mostrati di seguito:
C:\Users\admin>elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------------------------------------------------
> 7>2
True : Bool
> 7.0>2
True : Bool
> 7.0<2.0
False : Bool
> 'a' > 'b'
False : Bool
> 'a' < 'b'
True : Bool
> "a" < "b"
True : Bool
> (1,2) > (2,3)
False : Bool
> ['1','3'] < ['2','1']
True : Bool
>
Operatori logici
Gli operatori logici vengono utilizzati per combinare due o più condizioni. Anche gli operatori logici restituiscono un valore booleano.
Mostra esempi
Sr. No. | Operatore | Descrizione | Esempio |
---|---|---|---|
1 | && | L'operatore restituisce true solo se tutte le espressioni specificate restituiscono true | (10> 5) && (20> 5) restituisce True |
2 | || | L'operatore restituisce true se almeno una delle espressioni specificate restituisce true | (10 <5) || (20> 5) restituisce True |
3 | non | L'operatore restituisce l'inverso del risultato dell'espressione. Ad esempio:! (> 5) restituisce false. | not (10 <5) restituisce True |
4 | xor | L'operatore restituisce true solo se esattamente un input restituisce true. L'operatore restituisce false se entrambe le espressioni restituiscono true. | xor (10> 5) (20> 5) restituisce false |
Le strutture decisionali richiedono che il programmatore specifichi una o più condizioni che devono essere valutate o testate dal programma, insieme a una o più istruzioni da eseguire se la condizione è determinata essere vera e, facoltativamente, altre istruzioni da eseguire se condizione è determinata essere falsa.
Di seguito è mostrata la forma generale di una tipica struttura decisionale presente nella maggior parte dei linguaggi di programmazione
Un costrutto decisionale valuta una condizione prima che le istruzioni vengano eseguite. I costrutti decisionali in Elm sono classificati come segue:
Sr. No. | Dichiarazione | Descrizione |
---|---|---|
1 | if ... then ... else dichiarazione | L'istruzione if consiste in un'espressione booleana seguita da then che viene eseguita se l'espressione restituisce true e altrimenti che viene eseguita se l'espressione restituisce false |
2 | istruzione if annidata | Puoi usarne uno se ... allora ... altrimenti dentro un altro se. |
3 | dichiarazione del caso | Verifica il valore di una variabile rispetto a un elenco di valori. |
if ... then ... else Statement
Il if…thencostrutto valuta una condizione prima che venga eseguito un blocco di codice. Se l'espressione booleana restituisce true, verrà eseguito il blocco di codice all'interno dell'istruzione then. Se l'espressione booleana restituisce false, verrà eseguito il blocco di codice all'interno dell'istruzione else.
A differenza di altri linguaggi di programmazione, in Elm dobbiamo fornire il ramo else. Altrimenti, Elm genererà un errore.
Sintassi
if boolean_expression then statement1_ifTrue else statement2_ifFalse
Illustrazione
Prova il seguente esempio nel terminale REPL.
> if 10>5 then "10 is bigger" else "10 is small"
"10 is bigger" : String
Annidato If
L'istruzione if annidata è utile per testare più condizioni. La sintassi di un'istruzione if annidata è fornita di seguito:
if boolean_expression1 then statement1_ifTrue else if boolean_expression2 then statement2_ifTrue else statement3_ifFalse
Illustrazione
Prova il seguente esempio in Elm REPL -
> score=80
80 : number
> if score>=80 then "Outstanding" else if score > = 70 then "good" else "average"
"Outstanding" : String
Dichiarazione del caso
L'istruzione case può essere utilizzata per semplificare l'istruzione if then else. La sintassi di un'istruzione case è la seguente:
case variable_name of
constant1 -> Return_some_value
constant2 -> Return_some_value
_ -> Return_some_value if none of the above values match
L'istruzione case verifica se il valore di una variabile corrisponde a un insieme predefinito di costanti e restituisce il valore corrispondente. Notare che il valore restituito da ogni caso deve essere dello stesso tipo. Se il valore della variabile non corrisponde a nessuna delle costanti fornite, il controllo viene passato a * default * (indicato da // _) e viene restituito il valore corrispondente.
Illustrazione
Prova il seguente esempio in Elm REPL -
> n = 10
10 : number
> case n of \
| 0 -> "n is Zero" \
| _ -> "n is not Zero"
"n is not Zero" : String
Lo snippet di codice sopra controlla se il valore di n è zero. Il controllo viene passato al valore predefinito, che restituisce la stringa "n non è zero".
Elm è un linguaggio di programmazione funzionale. Elm utilizza il concetto di ricorsione come alternativa ai tradizionali costrutti di loop.
Questo capitolo discute il concetto di ricorsione.
Ricorsione
Alcuni linguaggi di programmazione per computer consentono a un modulo o una funzione di chiamare se stesso. Questa tecnica è nota come ricorsione.
Illustrazione
In questo programma vedremo come utilizzare la ricorsione per visualizzare ciao cinque volte.
Step 1 − Create a file Loop.elm
Crea un loop del modulo e definisci una funzione sayHello. La funzione sayHello accetta un valore intero come input e restituisce un valore stringa.
module Loop exposing(..)
//function signature
sayHello:Int ->String
//function implementation
sayHello n =
case n of
1 -> "Hello:1 "
_ -> "Hello:" ++ toString (n) ++ " " ++ sayHello(n-1)
The function sayHello checks if parameter passed is 1. If the parameter is 1, then function will return, otherwise it will create a string Hello and call the same function.
Step 2 − Invoke sayHello from REPL
Open the elm REPL from current project folder (location of Loop.elm file).
//import the module Loop
> import Loop exposing(..)
//invoke the sayHello function with parameter value as 5
> sayHello 5
"Hello:5 Hello:4 Hello:3 Hello:2 Hello:1 Hello:0 " : String
>
Illustration
The following example prints the sum of n numbers using recursion.
> sumOfNos n =\
| if n==0 then 0 \
| else (n) + sumOfNos (n-1)
<function> : number -> number1
In the elm REPL, we created a function sumOfNos that takes an input number and sums all numbers from 0 to that number.
For example, if we pass input as 5, it will sum up 1+2+3+4+5 which is 15.
> ssumOfNos 5
15 : number
The output of the program is shown above.
Functions are the building blocks of an Elm program. A function is a set of statements to perform a specific task.
Functions organize the program into logical blocks of code. Once defined, functions may be called to access code. This makes the code reusable. Moreover, functions make it easy to read and maintain the program’s code.
Steps to using a function
There are three steps to using a function −
Function Declaration
A function declaration tells the compiler about a function's name, return type, and parameters. The syntax for declaring a function is given below −
fn_name:data_type_of_the_parameters ->return_type
The function declaration specifies the following −
Name of the function.
Data type of the parameters. This is optional as a function may or may not have parameters.
Data type of the value, which the function will return. Functions in Elm must always return a value as Elm is a functional programming language. Unlike functions in other programing languages, Elm functions do not use the return keyword to return a value.
Function Definition or Function Implementation
A function definition provides the actual body of the function. A function definition specifies how a specific task would be done. The syntax for defining a function is as given below −
fn_name parameter1 parameter2 = statements
Invoking or Calling a Function
A function must be called so as to execute it. The syntax for calling a function is given below −
fn_name parameter1 parameter2
Illustration
The following code defines a function greet. The function returns a string "Hello".
> greet = \
| if True then \
| "Hello" \
| else \
| "GoodBye"
"Hello" : String
> greet
"Hello" : String
Parameterized Functions
Parameters are a mechanism to pass values to a function. The values of the parameters are passed to the function at the time of function invocation.
Illustration 1
The following example defines a function fn_add. The function accepts two numbers as parameters and returns their sum. Try the following in elm REPL −
> fn_add x y = x+y
<function> : number -> number -> number
> fn_add 10 20
30 : number
Illustration 2
The following example defines a function sayHello. The sayHello function accepts and returns a String value as parameter and returns a String.
> sayHello name = "Hello "++ name
<function> : String -> String
> sayHello "Tutorialspoint"
"Hello Tutorialspoint" : String
>
Pipe Operator
To understand pipe operator |>, let us consider an example where we have a list of different strings ["a","b","c"] . Now we need a single string, which is separated by −
The following example shows how to do that with String.join
> String.join "-" ["a","b","c","d","e","f"]
"a-b-c-d-e-f" : String
The same action can be performed by using a pipe operator |>. The pipe operator can be used to chain multiple function calls.
> ["a","b","c","d","e","f"] |> String.join "-"
"a-b-c-d-e-f" : String
> ["a","b","c","d","e","f"] |> List.reverse |> String.join "-"
"f-e-d-c-b-a" : String
In the first example, we are chaining the list to join method. In the second case, the same list is piped to reverse function and thereafter piped to join. So, the list is displayed in reversed and joined.
A sequence of Unicode characters is called a String. In Elm, strings are enclosed in "" double quotes. A String is a chunk of text as shown below.
> "TutorialsPoint"
"TutorialsPoint" : String
> location = "Hyderabad" --variable
"Hyderabad" : String
> location
"Hyderabad" : String
>
String Functions
Some common functions that can be used to query or manipulate string values are given below. Use REPL to try the examples given below.
Sr. No | Method | Description |
---|---|---|
1 | isEmpty : String -> Bool | checks string is empty |
2 | reverse : String -> String | reverses a input string |
3 | length : String -> Int | returns an integer length |
4 | append :String -> String -> String | appends two string and returns a new string |
5 | append :String -> Sconcat : List String -> String | appends a list of strings and returns a new string |
6 | split : String -> String -> List String | splits an input string using a given separator, returns a string list |
7 | slice : Int -> Int -> String -> String | returns a substring given a start , end index and input string |
8 | contains : String -> String -> Bool | returns true if second string contains the first one |
9 | toInt : String -> Result.Result String Int | parses a String to Integer |
10 | toInt : String -> Result.Result String Int | parses a String to Integer |
11 | toFloat : String -> Result.Result String Float | parses a String to float |
12 | fromChar : Char -> String | creates a string from a given character. |
13 | toList : String -> List Char | converts string to list of characters |
14 | fromList : List Char -> String | converts a list of characters into a String |
15 | toUpper : String -> String | converts input string to upper case |
16 | trim : String -> String | gets rid of whitespace on both sides of a string. |
17 | filter : (Char -> Bool) -> String -> String | filters set of characters from input string |
18 | map : (Char -> Char) -> String -> String | transforms every character in an input string |
isEmpty
This function can be used to determine if a string is empty. This function returns True if the supplied String is empty.
Syntax
String.isEmpty String_value
To check the signature of function, type the following in elm REPL −
> String.isEmpty
<function> : String -> Bool
Signature of the function shows Bool as return type and input type as String −
Illustration
> String.isEmpty ""
True : Bool
> String.isEmpty "Tutorialspoint"
False : Bool
> location = "Hyderabad"
"Hyderabad" : String
> String.isEmpty location
False : Bool
reverse
This function reverses a string.
Syntax
String.reverse String_value
To check the signature of function, type the following in elm REPL −
> String.reverse
<function> : String -> String
Signature of the function shows String as return type and input type as String −
Illustration
> String.reverse "TutorialsPoint"
"tnioPslairotuT" : String
length
This function returns the length of a string.
Syntax
String.length String_value
To check the signature of function, type the following in elm REPL −
> String.length
<function-> : String -> Int
Signature of the function shows Int as return type and input type as String.
Illustration
> String.length "Mohtashim"
9 : Int
append
This function returns a new string by appending two strings.
Syntax
String.append String_value1 String_value2
To check the signature of function, type the following in elm REPL −
> String.append
<function-> : String -> String -> String
Signature of shows two String input parameters and one String output parameter
Illustration
> String.append "Tutorials" "Point"
TutorialsPoint : String
concat
This function returns a new string by concatenating many strings into one.
Syntax
String.concat [String1,String2,String3]
To check the signature of function, type the following in elm REPL −
> String.concat
<function> : List String -> String
Signature of shows a List of String input parameter and String return type
Illustration
> String.concat ["Hello","Tutorials","Point"]
HelloTutorialsPoint : String
split
This function splits a string using a given separator.
Syntax
String.split string_seperator String_value
To check the signature of function, type the following in elm REPL −
> String.split
<function> : String -> String -> List String
Signature of shows two input String parameters and output as a list of string type.
Illustration
> String.split "," "Hello,Tutorials,Point"
["Hello","Tutorials","Point"] : List String
slice
This function returns a substring given a start and end index. Negative indexes are taken starting from the end of the list. The value of the index starts from zero.
Syntax
String.slice start_index end_index String_value
To check the signature of function, type the following in elm REPL −
> String.slice
<function> : Int -> Int -> String -> String
Signature of shows three input parameter and one return type.
Illustration
> String.slice 0 13 "TutorialsPoint"
"TutorialsPoin" : String
contains
This function returns a True if the second string contains the first one.
Syntax
String.contains string1 string2
To check the signature of function, type the following in elm REPL −
> String.contains
<function> : String -> String -> Bool
Signature of shows bool return type and two input parameters
Illustration
> String.contains "Point" "TutorialsPoint"
True : Bool
toInt
This function converts a string into an int.
Syntax
String.toInt string_value
To check the signature of function, type the following in elm REPL −
> String.toInt
<function> : String -> Result.Result String Int
Since toInt can return error, the return type is Result, which is String or Int.
Illustration
> String.toInt "20"
Ok 20 : Result.Result String Int
> String.toInt "abc"
Err "could not convert string 'abc' to an Int" : Result.Result String Int
toFloat
This function converts a string into a float.
Syntax
String.toFloat string_value
To check the signature of function, type the following in elm REPL −
> String.toFloat
<function> : String -> Result.Result String Float
Since toFloat can return error, the return type is Result, which is String or Float.
Illustration
> String.toFloat "20.50"
Ok 20.5 : Result.Result String Float
> String.toFloat "abc"
Err "could not convert string 'abc' to a Float" : Result.Result String Float
fromChar
This function creates a string from a given character.
Syntax
String.fromChar character_value
To check the signature of function type following in elm REPL −
> String.fromChar
<function> : Char -> String
The signature shows String as return type and input as Char type
Illustration
> String.fromChar 'c'
"c" : String
toList
This function converts a string to a list of characters.
Syntax
String.toList string_value
To check the signature of function, type the following in elm REPL −
> String.toList
<function> : String -> List Char
The signatures shows function returns a list of characters and takes input a string.
Illustration
> String.toList "tutorialspoint"
['t','u','t','o','r','i','a','l','s','p','o','i','n','t'] : List Char
fromList
This function converts a list of characters into a String.
Syntax
String.fromList list_of_characters
To check the signature of function, type the following in elm REPL −
> String.fromList
<function> : List Char -> String
The signatures shows function returns a list of characters and takes input a string.
Illustration
> String.fromList ['h','e','l','l','o']
"hello" : String
toUpper
This function converts a string to all upper case.
Syntax
String.toUpper String_value
To check the signature of function, type the following in elm REPL −
> String.toUpper
<function> : String -> String
Illustration
> String.toUpper "hello"
"HELLO" : String
toLower
This function converts a string to all lower case.
Syntax
String.toLower String_value
To check the signature of function, type the following in elm REPL −
> String.toLower
<function> : String -> String
Illustration
> String.toLower "AbCd"
"abcd" : String
trim
This function gets rid of whitespace on both sides of a string.
Syntax
String.trim String_value
To check the signature of function, type the following in elm REPL −
> String.trim
<function> : String -> String
Illustration
> String.trim "tutorialspoint "
"tutorialspoint" : String
filter
This function filters a set of characters from input String. Keep only the characters that pass the test.
Syntax
String.filter test_function string_value
To check the signature of function, type the following in elm REPL −
> String.filter
<function> : (Char -> Bool) -> String -> String
The signature shows filter takes two input parameters and returns a String. The first parameter is a function, which has input Char and returns Bool.
Illustration
In the example, we are passing Char.isUpper as parameter to filter method; it returns all upper-case characters as shown below.
> import Char
> String.filter Char.isUpper "abcDEF"
"DEF" : String
map
This function takes a String and transforms every character in a string.
Syntax
String.filter mapping_function string_value
To check the signature of function, type the following in elm REPL −
> String.map
<function> : (Char -> Char) -> String -> String
Illustration
The following example replaces the character o with @ −
> String.map (\c -> if c == 'o' then '@' else c) "TutorialsPoint"
"Tut@rialsP@int" : String
The List, Tuples and Record data structures can be used to store a collection of values.
This chapter discusses how to use List in Elm.
A List is a collection of homogeneous values. The values in a list must all be of the same data type.
Consider the following limitations while using variables to store values −
Variables are scalar in nature. In other words, at the time of declaration a variable can hold only one value. This means that to store n values in a program, n variable declarations will be needed. Hence, the use of variables is not feasible when one needs to store a larger collection of values.
Variables in a program are allocated memory in random order, thereby making it difficult to retrieve/read the values in the order of their declaration.
Syntax
List_name = [value1,value2,value3.....valuen]
Illustration
The following example shows how to use a List in Elm. Try this example in elm REPL −
> myList1 = [10,20,30]
[10,20,30] : List number
> myList2 = ["hello","world"]
["hello","world"] : List String
If we try adding values of different types into a list, the compiler will throw a type mismatch error. This is shown below.
> myList = [1,"hello"]
-- TYPE MISMATCH
---------------------------------------------
repl-temp-000.elm
The 1st and 2nd entries in this list are different types of values.
4| [1,"hello"]
^^^^^^^
The 1st entry has this type:
number
But the 2nd is:
String
List operations
Following table shows the common operations on a List −
Sr. No | Method | Description |
---|---|---|
1 | isEmpty : List a -> Bool | checks if list is empty |
2 | reverse : List a -> Bool | reverses input list |
3 | length : List a -> Int | returns size of the list |
4 | maximum : List comparable -> Maybe.Maybe comparable | returns maximum value |
5 | minimum : List comparable -> Maybe.Maybe comparable | returns minimum value |
6 | sum : List number -> number | returns sum of all elements in list |
7 | product : List number -> number | checks if list is empty |
8 | sort : List comparable -> List comparable | sorts list in ascending order |
9 | concat : List (List a) -> List a | merges a bunch of list into one |
10 | append : List a -> List a -> List a | merges two lists together |
11 | range : Int -> Int -> List Int | returns a list of numbers from start to end |
12 | filter : (a -> Bool) -> List a -> List a | filters list of values from input list |
13 | head : List a -> Maybe.Maybe a | returns the first element from list |
14 | tail : : List a -> Maybe.Maybe (List a) | returns all elements except the head |
isEmpty
This function returns true if a list is empty.
Syntax
List.isEmpty list_name
To check the signature of function, type the following in elm REPL −
> List.isEmpty
<function> : List a -> Bool
Illustration
> List.isEmpty
<function> : List a -> Bool
> List.isEmpty [10,20,30]
False : Bool
reverse
This function reverses the list.
Syntax
List.reverse list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.reverse
<function> : List a -> List a
Illustrazione
> List.reverse [10,20,30]
[30,20,10] : List number
lunghezza
Questa funzione restituisce la lunghezza di un elenco.
Sintassi
List.length list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.length
<function> : List a -> Int
Illustrazione
> List.length [10,20,30]
3 : Int
massimo
Questa funzione restituisce l'elemento massimo in un elenco non vuoto.
Sintassi
List.maximum list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.maximum
<function> : List comparable -> Maybe.Maybe comparable
Illustrazione
> List.maximum [10,20,30]
Just 30 : Maybe.Maybe number
> List.maximum []
Nothing : Maybe.Maybe comparable
minimo
Questa funzione restituisce l'elemento minimo in un elenco non vuoto.
Sintassi
List.minimum list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.minimum
<function> : List comparable -> Maybe.Maybe comparable
Illustrazione
> List.minimum [10,20,30]
Just 10 : Maybe.Maybe number
somma
Questa funzione restituisce la somma di tutti gli elementi in un elenco.
Sintassi
List.sum list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.sum
<function> : List number -> number
Illustrazione
> List.sum [10,20,30]
60 : number
Prodotto
Questa funzione restituisce il prodotto di tutti gli elementi in un elenco.
Sintassi
List.product list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
<function> : List number -> number
Illustrazione
List.product [10,20,30]
6000 : number
ordinare
Questa funzione ordina i valori dal più basso al più alto in un elenco.
Sintassi
List.sort list_name
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.sort
<function> : List comparable -> List comparable
Illustrazione
> List.sort [10,20,30]
[10,20,30] : List number
concat
Questa funzione concatena un gruppo di elenchi in un unico elenco.
Sintassi
List.concat [ [list_name1],[list_name2],[list_name3],.....[list_nameN] ]
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.concat
<function> : List (List a) -> List a
Illustrazione
> List.concat [[10,20], [30,40],[50,60]]
[10,20,30,40,50,60] : List number
aggiungere
Questa funzione mette insieme due elenchi.
Sintassi
List.append [list_name1] [list_name2]
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.append
<function> : List a -> List a -> List a
Illustrazione
> List.append [10,20] [30,40]
[10,20,30,40] : List number
L'operatore ++ può anche essere utilizzato per aggiungere un elenco a un altro. Questo è mostrato nell'esempio sotto:
> [10.1,20.2] ++ [30.3,40.4]
[10.1,20.2,30.3,40.4] : List Float
gamma
Questa funzione crea un elenco di numeri, ogni elemento aumenta di uno. Il numero più basso e quello più alto che dovrebbero essere nella lista vengono passati alla funzione.
Sintassi
List.range start_range end_range
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.range
<function> : Int -> Int -> List Int
Illustrazione
> List.range 1 10
[1,2,3,4,5,6,7,8,9,10] : List Int
filtro
Questa funzione filtra un insieme di valori dall'elenco di input. Conserva solo i valori che superano il test.
Sintassi
List.filter test_function input_list
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.filter
<function> : (a -> Bool) -> List a -> List a
Illustrazione
L'esempio seguente filtra tutti i numeri pari da un elenco di input
> List.filter (\n -> n%2==0) [10,20,30,55]
[10,20,30] : List Int
testa
Questa funzione restituisce il primo elemento dall'elenco di input.
Sintassi
List.head input_list
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.head
<function> : List a -> Maybe.Maybe a
Illustrazione
> List.head [10,20,30,40]
Just 10 : Maybe.Maybe number
> List.head []
Nothing : Maybe.Maybe a
coda
Questa funzione restituisce tutti gli elementi dopo i primi nell'elenco.
Sintassi
List.tail input_list
Per controllare la firma della funzione, digitare quanto segue in elm REPL -
> List.tail
<function> : List a -> Maybe.Maybe (List a)
Illustrazione
> List.tail [10,20,30,40,50]
Just [20,30,40,50] : Maybe.Maybe (List number)
> List.tail [10]
Just [] : Maybe.Maybe (List number)
> List.tail []
Nothing : Maybe.Maybe (List a)
Utilizzando l'operatore Contro
L'operatore contro (::) aggiunge un elemento all'inizio di una lista.
Illustrazione
> 10::[20,30,40,50]
[10,20,30,40,50] : List number
Il nuovo elemento da aggiungere e il tipo di dati dei valori nell'elenco devono corrispondere. Il compilatore genera un errore se i tipi di dati non corrispondono.
> [1,2,3,4]::[5,6,7,8]
-- TYPE MISMATCH ---------------------------------
------------ repl-temp-000.elm
The right side of (::) is causing a type mismatch.
3| [1,2,3,4]::[5,6,7,8]
^^^^^^^^^
(::) is expecting the right side to be a:
List (List number)
But the right side is:
List number
Hint: With operators like (::) I always check the left side first. If it seems fine,
I assume it is correct and check the right side. So the
problem may be in how the left and right arguments interact.
Le liste sono immutabili
Controlliamo se le liste sono immutabili in Elm. Il primo elenco myList quando concatenato con il valore 1 crea un nuovo elenco e viene restituito a myListCopy . Pertanto, se visualizziamo l'elenco iniziale, i suoi valori non verranno modificati.
> myList = [10,20,30]
[10,20,30] : List number
> myListCopy = 1::myList
[1,10,20,30] : List number
> myList
[10,20,30] : List number
>myList == myListCopy
False : Bool
A volte, potrebbe essere necessario memorizzare una raccolta di valori di vari tipi. Elm ci fornisce una struttura dati chiamata tupla che serve a questo scopo.
Una tupla rappresenta una raccolta eterogenea di valori. In altre parole, le tuple consentono di memorizzare più campi di diversi tipi. Una tupla memorizza un numero fisso di valori. Le tuple sono utili quando si desidera restituire più valori di tipi diversi da una funzione. Queste strutture dati sono immutabili come gli altri tipi in elm.
Sintassi
(data1,data2)
Di seguito viene mostrato un semplice esempio:
> ("TuotrialsPoint",5,True,"Hyderabad")
("TuotrialsPoint",5,True,"Hyderabad") : ( String, number, Bool, String )
Nelle nostre sezioni successive, impareremo le diverse operazioni sulle tuple.
primo
Questa operazione estrae il primo valore da una tupla.
Sintassi
Tuple.first tuple_name
> Tuple.first
<function> : ( a1, a2 ) -> a1
Illustrazione
> Tuple.first (10,"hello")
10 : number
secondo
Il second L'operazione tupla estrae il secondo valore da una tupla.
Sintassi
Tuple.second tuple_name
> Tuple.second
<function> : ( a1, a2 ) -> a2
Illustrazione
> Tuple.second (10,"hello")
"hello" : String
Elenco di tuple
Un elenco può archiviare tuple. Se all'interno di un elenco vengono utilizzate tuple, assicurati che siano tutte dello stesso tipo di dati e abbiano lo stesso numero di parametri.
Illustrazione
> [("hello",20),("world",30)]
[("hello",20),("world",30)] : List ( String, number )
Tupla con funzione
Una funzione può restituire tuple. Inoltre, le tuple possono essere passate come parametri alle funzioni.
Illustrazione 1
L'esempio seguente definisce una funzione fn_checkEven. Questa funzione accetta un valore intero come parametro e restituisce una tupla.
> fn_checkEven no = \
if no%2 == 0 then \
(True,"The no is Even")\
else \
(False,"No is not even")
<function> : Int -> ( Bool, String )
> fn_checkEven 10
(True,"The no is Even") : ( Bool, String )
> fn_checkEven 11
(False,"No is not even") : ( Bool, String )
>
Illustrazione 2
Quanto segue passa una tupla come parametro a una funzione.
> fn_add (a,b) = \
| a+b
<function> : ( number, number ) -> number
> fn_add (10,20)
30 : number
La funzione fn_add accetta una tupla con 2 valori numerici e restituisce la loro somma.
Destrutturante
La destrutturazione implica la suddivisione di una tupla in valori individuali. Per accedere a valori individuali in una tupla con tre o più elementi, usiamo la destrutturazione. Qui, assegniamo ogni valore in una tupla a diverse variabili. Utilizzando _ è possibile definire segnaposto per valori che verranno ignorati o ignorati.
Illustrazione
> (first,_,_) = (10,20,30)
10 : number
> first
10 : number
Illustrazione
In questo esempio, useremo la sintassi del blocco let..in per destrutturare. Il blocco let contiene le variabili e il blocco in contiene le espressioni che dovrebbero essere valutate e il valore che dovrebbe essere restituito.
> t1 = (10,20,30)
(10,20,30) : ( number, number1, number2 )
> let \
(a,b,c) = t1 \
in\
a + b +c
60 : number
Stiamo dichiarando le variabili abc nella clausola let e accedendovi utilizzando la clausola in.
La struttura dei dati del record in Elm può essere utilizzata per rappresentare i dati come coppie chiave-valore. Un record può essere utilizzato per organizzare i dati correlati per consentire un facile accesso e aggiornamento dei dati. I record Elm sono simili agli oggetti in JavaScript. Gli elementi di dati in un record sono noti come campi.
Definizione di un record
Utilizzare la seguente sintassi per definire un record:
Sintassi
record_name = {fieldname1 = value1, fieldname2 = value2....fieldnameN = valueN}
Un record può memorizzare dati di più tipi. I nomi dei campi in un record devono essere conformi alle regole generali per la denominazione di un identificatore Elm.
Accesso ai valori dei record
Utilizzare la seguente sintassi per accedere ai singoli campi in un record.
Sintassi
record_name.fieldname
O
.fieldname record_name
Illustrazione
Prova quanto segue in Elm REPL -
> company = {name="TutorialsPoint",rating=4.5}
{ name = "TutorialsPoint", rating = 4.5 } : { name : String, rating : Float }
> company.name
"TutorialsPoint" : String
> .rating company
4.5 : Float
Utilizzo di Record with List
Un record può essere memorizzato all'interno di un elenco. Tutti i valori di campo del record devono essere dello stesso tipo.
Sintassi
list_name = [ {field_name1 = value1},{field_name1 = value2}]
O
list_name = [record_name1, record_name2, record_name3....record_nameN]
Illustrazione
Prova quanto segue in Elm REPL -
> [{name = "Mohtashim"},{name = "kannan"}]
[{ name = "Mohtashim" },{ name = "kannan" }] : List { name : String }
> record1 = {name = "FirstRecord"}
{ name = "FirstRecord" } : { name : String }
> record2 = {name = "SecondRecord"}
{ name = "SecondRecord" } : { name : String }
> recordList = [record1,record2]
[{ name = "FirstRecord" },{ name = "SecondRecord" }] : List { name : String }
Aggiorna un record
I record sono immutabili in Elm. Quando un record viene aggiornato, viene restituito un nuovo record con valori aggiornati. Il campo può contenere un valore di un tipo diverso durante l'aggiornamento di un record.
Sintassi
{record_name | field_name1 = new_value1, field_name2 = new_value2,field_name3 = new_value3....field_nameN = new_valueN}
Illustrazione
Prova quanto segue in Elm REPL -
> record1 = {name="FirstRecord"}
{ name = "FirstRecord" } : { name : String }
> record1_updated = {record1 | name = "FirstRecordUpdate"}
{ name = "FirstRecordUpdate" } : { name : String }
> record1
{ name = "FirstRecord" } : { name : String }
> record1 == record1_updated
False : Bool
Illustrazione
Il seguente esempio aggiorna più campi di un record. Prova quanto segue in Elm REPL -
> record3 = {a = 1,b = 2,c = 3,d = 4,e = 5}
{ a = 1, b = 2, c = 3, d = 4, e = 5 }
: { a : number, b : number1, c : number2, d : number3, e : number4 }
> record4 = {record3 | d=400 ,e=500}
{ a = 1, b = 2, c = 3, d = 400, e = 500 }
: { a : number2, b : number3, c : number4, d : number, e : number1 }
>
Alias dei tipi
L'alias di tipo definisce uno schema per un record. In altre parole, un alias di tipo definisce quali campi possono essere archiviati nel record e il tipo di valore che questi campi possono memorizzare. Pertanto, il programmatore non commetterà l'errore di perdere alcun attributo specifico durante l'assegnazione dei valori.
Sintassi
type alias alias_name = {field_name1:data_type,field_name2:data_type,....field_nameN:data_type}
Illustrazione
Eseguire quanto segue in Elm REPL -
> type alias Developer = { name:String,location:String,age:Int}
> dev1 = Developer "kannan" "Mumbai" 20
{ name = "kannan", location = "Mumbai", age = 20 } : Repl.Developer
> dev2 = Developer "mohtashim" "hyderabad" 20
{ name = "mohtashim", location = "hyderabad", age = 20 } : Repl.Developer
>
Ora, se dimentichi di digitare location ed age, l'istruzione restituisce una funzione, che ha parametri di input per i campi location ed age.
> dev3 = Developer "Bhagavati"
<function> : String -> Int -> Repl.Developer
We can invoke the function as shown below and pass to it the values for location and age fields.
> dev3 "Pune" 25
{ name = "Bhagavati", location = "Pune", age = 25 } : Repl.Developer
Un errore è una condizione imprevista in un programma. Gli errori possono verificarsi in fase di compilazione o in fase di esecuzione. Errori in fase di compilazione si verificano durante la compilazione di un programma (ad esempio, errore nella sintassi del programma) mentre errori di runtime si verificano durante l'esecuzione del programma. A differenza di altri linguaggi di programmazione, Elm non genera errori di runtime.
Considera un'applicazione che accetta l'età di un utente. L'applicazione dovrebbe generare un errore se l'età è zero o negativa. In questo caso, l'applicazione Elm può utilizzare il concetto di gestione degli errori per sollevare esplicitamente un errore in fase di esecuzione se l'utente immette zero o un valore negativo come età. La gestione degli errori specifica il corso dell'azione in caso di imprevisti durante l'esecuzione del programma.
Il linguaggio di programmazione Elm gestisce gli errori nei seguenti modi:
- MayBe
- Result
Può essere
Considera la funzione di ricerca in un'applicazione. La funzione di ricerca restituisce i dati correlati se la parola chiave di ricerca viene trovata altrimenti non restituisce nulla. Questo caso d'uso può essere implementato in Elm utilizzando il tipo MayBe.
Sintassi
variable_name:MayBe data_type
Una variabile di tipo MayBe può contenere uno dei seguenti valori:
Solo some_Value: viene utilizzato se sono presenti dati validi.
Niente: viene utilizzato se il valore è assente o sconosciuto. Niente è equivalente a null in altri linguaggi di programmazione.
Illustrazione
L'esempio seguente mostra come utilizzare il tipo MayBe con variabili e funzioni.
Step 1 - Crea un file MayBeDemo.elm file e aggiungi il codice seguente
-- MayBeDemo.elm
module MayBeDemo exposing(..)
import Maybe
--declaring a MayBe variable and assigning value to it
userName : Maybe String
userName = Just "Mohtashim"
--declaring a MayBe variable and assigning value to it
userAge :Maybe Int
userAge = Just 20
--declaring a MayBe variable and assigning value to it
userSalary:Maybe Float
userSalary = Nothing
--declaring a custom type
type Country = India | China | SriLanka
--defining a function that takes a String parameter as input and returns a value of type MayBe
getCountryFromString : String -> Maybe Country
getCountryFromString p =
case p of
"India"
-> Just India
"China"
-> Just China
"SriLanka"
-> Just SriLanka
_
-> Nothing
Step 2 - Importare il modulo in elm repl ed eseguire come indicato di seguito
E:\ElmWorks\ErroApp> elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at
-------------------------------------------------------------------------------- > import MayBeDemo exposing(..) > userName Just "Mohtashim" : Maybe.Maybe String > userAge Just 20 : Maybe.Maybe Int > userSalary Nothing : Maybe.Maybe Float > getCountryFromString "India" Just India : Maybe.Maybe MayBeDemo.Country > getCountryFromString "india" Nothing : Maybe.Maybe MayBeDemo.Country
La funzione controlla se il valore passato alla funzione è India, Cina o SriLanka. Se il valore del parametro non corrisponde a nessuno di questi, non restituisce nulla.
Risultato
Considera un esempio, in cui l'applicazione deve convalidare una condizione e generare un errore se la condizione non è soddisfatta. Il tipo di risultato può essere utilizzato per ottenere ciò. Il tipo di risultato deve essere utilizzato se l'applicazione desidera sollevare esplicitamente un errore e restituire dettagli su cosa è andato storto.
Sintassi
La dichiarazione del tipo di risultato accetta due parametri: il tipo di dati dell'errore (solitamente String) e il tipo di dati del risultato da restituire se tutto va bene.
type Result error_type data_value_type
= Ok data_value
| Err error_message
Il tipo di risultato restituisce uno dei seguenti valori:
Ok some_value - Rappresenta il risultato da restituire
Err - Rappresenta il messaggio di errore da restituire se le condizioni previste non sono soddisfatte.
Illustrazione 1
Prova il seguente esempio in Elm REPL -
> String.toInt
<function> : String -> Result.Result String Int
-- successful result
> String.toInt "10"
Ok 10 : Result.Result String Int
-- unsuccessful result , Error
> String.toInt "a"
Err "could not convert string 'a' to an Int" : Result.Result String Int
La funzione String.toInt restituisce il valore Integer se il parametro passato è valido. Se il parametro non è un numero, la funzione restituisce un errore.
Illustrazione 2
L'esempio seguente accetta l'età come parametro. La funzione restituisce l'età se è compresa tra 0 e 135 altrimenti restituisce un messaggio di errore appropriato.
Step 1 - Crea un file ResultDemo.elm e aggiungi il codice seguente.
--ResultDemo.elm
module ResultDemo exposing(..)
userId : Result String Int
userId = Ok 10
emailId : Result String Int
emailId = Err "Not valid emailId"
isReasonableAge : String -> Result String Int
isReasonableAge input =
case String.toInt input of
Err r ->
Err "That is not a age!"
Ok age ->
if age < 0 then
Err "Please try again ,age can't be negative"
else if age > 135 then
Err "Please try agian,age can't be this big.."
else
Ok age
Step 2 - Importa il modulo nel pacchetto elm ed esegui come indicato di seguito
E:\ElmWorks\ElmRepo\15_ErrorHandling\15_Code> elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------------------------------------------------
> import ResultDemo exposing (..)
> userId
Ok 10 : Result.Result String Int
> emailId
Err "Not valid emailId" : Result.Result String Int
> isReasonableAge "10"
Ok 10 : Result.Result String Int
> isReasonableAge "abc"
Err "That is not a age!" : Result.Result String Int
In questo capitolo, discuteremo il modo standard per creare applicazioni nella piattaforma Elm. Elm utilizza un pattern architettonico simile al pattern Model-View-Controller.
Di seguito sono riportate le quattro parti principali di Elm Architecture.
- Model
- View
- Message
- Update
Come funziona l'architettura Elm
Il modelcontiene lo stato dell'applicazione. Ad esempio, se un'applicazione visualizza un elenco di clienti, lo stato conterrà i dati di ciascun cliente. Per visualizzare lo stato in modo presentabile, aview/ html deve essere generato. Una volta che l'utente interagisce con la vista premendo un pulsante o digitando i dati in un modulo, la vista genera segnali chiamatimessages. I messaggi vengono passati al fileupdatemetodo, che valuta i messaggi e intraprende le azioni appropriate. Pertanto, il metodo di aggiornamento genererà un nuovo modello.
Il nuovo modello genera una nuova vista. La visualizzazione porterà a nuove interazioni da parte dell'utente ai messaggi di segnalazione, che va alla funzione di aggiornamento. Inoltre, la funzione crea un nuovo modello. Quindi, il ciclo si ripete come mostrato nel diagramma sopra.
Modello
Il modello si occupa dello stato dell'applicazione. La sintassi per la definizione di un modello è fornita di seguito:
-- Model syntax
type alias Model = {
property1:datatype,
proptery2:datatype
...
}
Per creare un modello, dobbiamo prima creare un modello con tutte le proprietà richieste al suo interno. Ogni proprietà specifica lo stato dell'applicazione.
Visualizza
La vista è una rappresentazione visiva dello stato dell'applicazione. The View sa come estrarre dati e generare pagine web da essi. Quando un utente interagisce con la vista, può manipolare lo stato generando messaggi. Di seguito viene fornita la sintassi per la definizione di una vista:
--View Syntax
view model =some_implementation
Messaggio
Il messaggio è una richiesta dell'utente per modificare lo stato dell'applicazione. I messaggi vengono passati come parametri alla funzione di aggiornamento.
--Message Syntax
type Message = Message1 |Message2 ...
La sintassi mostra un tipo Message. L'applicazione elm modificherà lo stato in base ai messaggi ad essa passati. Queste decisioni vengono prese nel metodo di aggiornamento.
Aggiornare
La funzione di aggiornamento interpreta i messaggi, che le vengono passati come parametro, e aggiorna il modello.
--Update Syntax
update Message_type model =
some_implementation
La funzione di aggiornamento richiede Message e Modello come parametri.
Un gestore di pacchetti è uno strumento della riga di comando che automatizza il processo di installazione, aggiornamento, configurazione e rimozione dei pacchetti nell'applicazione.
Proprio come JavaScript ha un gestore di pacchetti chiamato npm, elm ha un gestore di pacchetti chiamato elm-package .
Il gestore di pacchetti esegue le seguenti tre attività:
- Installa tutte le dipendenze necessarie a un'applicazione elm
- Pubblica pacchetti personalizzati
- Determina la versione del pacchetto quando sei pronto per la pubblicazione e l'aggiornamento.
Comandi di Elm Package Manager
La tabella seguente elenca i vari comandi del gestore di pacchetti Elm:
Sr. No. | Comando | Sintassi | Descrizione |
---|---|---|---|
1 | installare | installazione del pacchetto elm | Installa i pacchetti da utilizzare localmente |
2 | pubblicare | pubblicazione del pacchetto elm | Pubblica il tuo pacchetto nel catalogo centrale |
3 | urto | urto pacchetto olmo | Aumenta i numeri di versione in base alle modifiche all'API |
4 | diff | elm-package diff | Ottiene le differenze tra due API |
Per pubblicare il tuo pacchetto, devi ospitare il codice sorgente su GitHub e avere la versione correttamente etichettata con un tag git. La seguente illustrazione mostra come utilizzare elm-package manager per estrarre una dipendenza esterna.
Illustrazione - Installazione del pacchetto svg
In questo esempio, vedremo come integrare Scalable Vector Graphics (SVG) in un'applicazione elm.
Step 1 - Crea una cartella elmSvgApp
Step 2 - Installa il pacchetto svg utilizzando il seguente comando -
elm-package install elm-lang/svg
Step 3- Installa Crea un file SvgDemo.elm e digita il contenuto indicato di seguito. Importiamo il modulo Svg per disegnare un rettangolo di dimensione 100x100 e riempire il colore rosso.
import Svg exposing (..)
import Svg.Attributes exposing (..)
main =
svg
[ width "120"
, height "120"
, viewBox "0 0 120 120"
]
[ rect
[ x "10"
, y "10"
, width "100"
, height "100"
, rx "15"
, ry "15"
,fill "red"
]
[]
]
Step 4- Ora crea il progetto usando elm make. \ SvgDemo.elm. Questo genererà un index.html come mostrato di seguito -
Il messaggio è un componente dell'architettura Elm. Questi componenti vengono generati dalla vista in risposta all'interazione dell'utente con l'interfaccia dell'applicazione. I messaggi rappresentano le richieste dell'utente per modificare lo stato dell'applicazione.
Sintassi
--Message Syntax
type Message = some_message1 |some_message2 ...|some_messageN
llustration
L'esempio seguente è una semplice applicazione contatore. L'applicazione incrementa e decrementa il valore di una variabile di 1 quando l'utente fa clic rispettivamente sui pulsanti Aggiungi e Sottrai.
L'applicazione avrà 4 componenti. I componenti sono descritti di seguito:
Messaggio
I messaggi per questo esempio saranno:
type Message = Add | Subtract
Modello
Il modello rappresenta lo stato dell'applicazione. Nella contro domanda la definizione del modello è data di seguito; lo stato iniziale del contatore sarà zero.
model = 0
Visualizza
La vista rappresenta gli elementi visivi dell'applicazione. La vista contiene due pulsanti (+) e (-). I messaggi Aggiungi e Sottrai vengono generati dalla Vista quando l'utente fa clic rispettivamente sui pulsanti + e -. Il valore modificato del modello viene quindi visualizzato dalla vista.
view model =
-- invoke text function
h1[]
[ div[] [text "CounterApp from TutorialsPoint" ]
,button[onClick Subtract] [text "-"]
,div[][text (toString model)]
,button[onClick Add] [text "+"]
]
Aggiornare
Questo componente contiene codice che dovrebbe essere eseguito per ogni messaggio generato dalla vista. Questo è mostrato nell'esempio sotto:
update msg model =
case msg of
Add -> model+1
Subtract -> model-1
Mettere tutto insieme
Step 1- Crea una cartella MessagesApp e un file MessagesDemo.elm
Step 2 - Aggiungi il seguente codice nel file elm -
import Html exposing (..)
import Html.Events exposing(onClick)
model = 0 -- Defining the Model
--Defining the View
view model =
h1[]
[ div[] [text "CounterApp from TutorialsPoint" ]
,button[onClick Subtract] [text "-"]
,div[][text (toString model)]
,button[onClick Add] [text "+"]
]
--Defining the Messages
type Message = Add | Subtract
--Defining Update
update msg model =
case msg of
Add -> model+1
Subtract -> model-1
-- Define the main method
main =
beginnerProgram
{
model=model
,view=view
,update=update
}
Step 3 - Esegui il file elm make commandnel terminale. Ilelm make command compila il codice e genera un file HTML dal file .elm creato sopra.
C:\Users\dell\elm\MessagesApp> elm make .\MessageDemo.elm
Some new packages are needed. Here is the upgrade plan.
Install:
elm-lang/core 5.1.1
elm-lang/html 2.0.0
elm-lang/virtual-dom 2.0.4
Do you approve of this plan? [Y/n] y
Starting downloads...
ΓùÅ elm-lang/html 2.0.0
ΓùÅ elm-lang/virtual-dom 2.0.4
ΓùÅ elm-lang/core 5.1.1
Packages configured successfully!
Success! Compiled 38 modules.
Successfully generated index.html
Step 4 - Apri il file index.html e verificare il funzionamento come mostrato di seguito -
Elm - Comandi
Nei capitoli precedenti, abbiamo discusso i vari componenti dell'architettura Elm e le loro funzioni. L'utente e l'applicazione comunicano tra loro utilizzando Messaggi.
Considera un esempio, in cui l'applicazione deve comunicare con altri componenti come un server esterno, API, microservizi, ecc. Per soddisfare la richiesta dell'utente. Ciò può essere ottenuto utilizzando i comandi in Elm. I messaggi e i comandi non sono sinonimi. I messaggi rappresentano la comunicazione tra un utente finale e l'applicazione mentre i comandi rappresentano il modo in cui un'applicazione Elm comunica con altre entità. Un comando viene attivato in risposta a un messaggio.
La figura seguente mostra il flusso di lavoro di un'applicazione Elm complessa:
L'utente interagisce con la vista. La vista genera un messaggio appropriato in base all'azione dell'utente. Il componente di aggiornamento riceve questo messaggio e attiva un comando.
Sintassi
La sintassi per definire un comando è la seguente:
type Cmd msg
Il messaggio generato dalla visualizzazione viene passato al comando.
Illustrazione
L'esempio seguente effettua una richiesta a un'API e visualizza il risultato dall'API.
L'applicazione accetta un numero dall'utente, lo passa all'API Numbers. Questa API restituisce fatti relativi al numero.
I vari componenti dell'applicazione sono i seguenti:
Modulo HTTP
Il modulo Http di Elm viene utilizzato per creare e inviare richieste HTTP. Questo modulo non fa parte del modulo principale. Useremo il gestore di pacchetti elm per installare questo pacchetto.
API
In questo esempio, l'applicazione comunicherà con l'API Numbers - "http://numbersapi.com/#42".
Visualizza
La visualizzazione dell'applicazione contiene una casella di testo e un pulsante.
view : Model -> Html Msg
view model =
div []
[ h2 [] [text model.heading]
,input [onInput Input, value model.input] []
, button [ onClick ShowFacts ] [ text "show facts" ]
, br [] []
, h3 [][text model.factText]
]
Modello
Il Modello rappresenta il valore inserito dall'utente e il risultato che verrà restituito dall'API.
type alias Model =
{ heading : String
, factText : String
, input :String
}
Messaggio
L'applicazione ha i seguenti tre messaggi:
- ShowFacts
- Input
- NewFactArrived
Facendo clic sul pulsante Mostra fatti , il messaggio ShowFacts viene passato al metodo di aggiornamento. Quando l'utente digita un valore nella casella di testo, il messaggio di input viene passato al metodo di aggiornamento. Infine, quando viene ricevuta la risposta del server HTTP , il messaggio NewFactArrived verrà passato all'aggiornamento.
type Msg
= ShowFacts
|Input String
| NewFactArrived (Result Http.Error String)
Aggiornare
Il metodo update restituisce una tupla, che contiene il modello e gli oggetti comando. Quando l'utente fa clic sul pulsante Mostra fatti, il messaggio viene passato all'aggiornamento che quindi chiama NumbersAPI.
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Input newInput ->
(Model "NumbersApi typing.." "" newInput ,Cmd.none)
ShowFacts ->
(model, getRadmonNumberFromAPI model.input)
NewFactArrived (Ok newFact) ->
(Model "DataArrived" newFact "", Cmd.none)
NewFactArrived (Err _) ->
(model, Cmd.none)
Funzione di aiuto
La funzione di supporto getRandomNumberFromAPI richiama NumbersAPI e gli passa il numero inserito dall'utente. Il risultato restituito dall'API viene utilizzato per aggiornare il modello.
getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
let
url =
"http://numbersapi.com/"++newNo
in
Http.send NewFactArrived (Http.getString url)
Sr. No. | Metodo | Firma | Descrizione |
---|---|---|---|
1 | Http.getString | getString: String -> Request String | Crea una richiesta GET e interpreta il corpo della risposta come una stringa. |
2 | Http. Invia | invia: (Errore risultato a -> msg) -> Richiedi a -> Cmd msg | Invia una richiesta Http. |
principale
Questo è il punto di ingresso del progetto Elm.
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Mettere tutto insieme
Step 1 - Crea la cartella CommandApp e il file CommandDemo.elm.
Step 2- Installa il modulo http usando il comando elm package install elm-lang / http .
Step 2 - Digita il contenuto per CommandDemo.elm come mostrato di seguito -
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ heading : String
, factText : String
, input :String
}
init : (Model, Cmd Msg)
init =
( Model "NumbersAPI" "NoFacts" "42"-- set model two fields
, Cmd.none -- not to invoke api initially
)
-- UPDATE
type Msg
= ShowFacts
|Input String
| NewFactArrived (Result Http.Error String)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Input newInput ->
(Model "NumbersApi typing.." "" newInput ,Cmd.none)
ShowFacts ->
(model, getRadmonNumberFromAPI model.input)
NewFactArrived (Ok newFact) ->
(Model "DataArrived" newFact "", Cmd.none)
NewFactArrived (Err _) ->
(model, Cmd.none)
- VIEW
view : Model -> Html Msg
view model =
div []
[ h2 [] [text model.heading]
,input [onInput Input, value model.input] []
, button [ onClick ShowFacts ] [ text "show facts" ]
, br [] []
, h3 [][text model.factText]
]
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- HTTP
getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
let
url =
"http://numbersapi.com/"++newNo
in
Http.send NewFactArrived (Http.getString url)
Step 4 - Aziona il comando.
C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm
Questo genererà il file html come mostrato di seguito.
Elm - Abbonamenti
Nel capitolo precedente, abbiamo discusso del fatto che una vista interagisce con altri componenti utilizzando i comandi. Allo stesso modo, un componente (ad esempio WebSocket) può parlare con una vista utilizzando gli abbonamenti. Gli abbonamenti sono un modo in cui un'applicazione Elm può ricevere input esterni come eventi tastiera, eventi timer ed eventi WebSocket.
La figura seguente spiega il ruolo delle sottoscrizioni in un'applicazione Elm. L'utente interagisce con un'applicazione Elm tramite messaggi. L'applicazione fornita utilizza WebSocket e ha due modalità di funzionamento:
- Invia dati lato client al server socket tramite comando
- Ricevi dati in qualsiasi momento dal server socket tramite abbonamento
Sintassi
La sintassi per definire un abbonamento è fornita di seguito:
type Sub msg
Illustrazione
Facci capire gli abbonamenti utilizzando un semplice esempio.
Nell'esempio riportato di seguito, l'applicazione invia un messaggio al server. Il server è un echo server, che risponde al client con lo stesso messaggio. Tutti i messaggi in arrivo vengono successivamente visualizzati in un elenco. Useremo WebSocket (protocollo wss) per essere in grado di ascoltare continuamente i messaggi dal server. Il WebSocket invierà l'input dell'utente al server utilizzando i comandi mentre utilizzerà la sottoscrizione per ricevere i messaggi dal server.
Di seguito sono riportati i vari componenti dell'applicazione:
Server Echo
È possibile accedere al server echo utilizzando il protocollo wss. Il server echo restituisce l'input dell'utente all'applicazione. Il codice per definire un server echo è fornito di seguito:
echoServer : String
echoServer =
"wss://echo.websocket.org"
Modello
Il modello rappresenta l'input dell'utente e un elenco di messaggi in arrivo dal server socket. Il codice per la definizione del Modello è il seguente:
type alias Model =
{ input : String
, messages : List String
}
Messaggi
Il tipo di messaggio conterrà Input per ricevere input di testo dall'utente. Il messaggio Invia verrà generato quando l'utente fa clic sul pulsante per inviare il messaggio al server WebSocket. Il NewMessage viene utilizzato quando il messaggio arriva dal server echo.
type Msg
= Input String
| Send
| NewMessage String
Visualizza
La visualizzazione dell'applicazione contiene una casella di testo e un pulsante di invio per inviare l'input dell'utente al server. La risposta del server viene visualizzata nella vista utilizzando un tag div .
view : Model -> Html Msg
view model =
div []
[ input [onInput Input, value model.input] []
, button [onClick Send] [text "Send"]
, div [] (List.map viewMessage (List.reverse model.messages))
]
viewMessage : String -> Html msg
viewMessage msg =
div [] [ text msg ]
Aggiornare
La funzione di aggiornamento accetta il messaggio e i componenti del modello. Aggiorna il modello in base al tipo di messaggio.
update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
case msg of
Input newInput ->
(Model newInput messages, Cmd.none)
Send ->
(Model "" messages, WebSocket.send echoServer input)
NewMessage str ->
(Model input (str :: messages), Cmd.none)
Sr. No. | Metodo | Firma | Descrizione |
---|---|---|---|
1 | WebSocket.listen | ascolta: String -> (String -> msg) -> Sub msg | Sottoscrive qualsiasi messaggio in arrivo su un websocket. |
2 | WebSocket.send | invia: String -> String -> Cmd msg | Invia una richiesta wss a un indirizzo del server. È importante che anche tu sia iscritto a questo indirizzo con ascolto. In caso contrario, verrà creato il web socket per inviare un messaggio e quindi chiuso. |
Sottoscrizione
La funzione di sottoscrizione accetta l'oggetto modello. Per ricevere i messaggi dal server WebSocket, chiamiamo WebSocket.listen passando il messaggio come NewMessage . Quando arriva un nuovo messaggio dal server, viene chiamato il metodo di aggiornamento.
subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen echoServer NewMessage
principale
La funzione principale è il punto di ingresso all'applicazione elm come mostrato di seguito.
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Mettere tutto insieme
Step 1 - Crea una directory, SubscriptionApp e aggiungi un file, SubscriptionDemo.elm ad essa.
Step 2 - Aggiungi i seguenti contenuti al file SubscriptionDemo.elm -
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import WebSocket
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
echoServer : String
echoServer =
"wss://echo.websocket.org"
-- MODEL
type alias Model =
{ input : String
, messages : List String
}
init : (Model, Cmd Msg)
init =
(Model "" [], Cmd.none)
-- UPDATE
type Msg
= Input String
| Send
| NewMessage String
update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
case msg of
Input newInput ->
(Model newInput messages, Cmd.none)
Send ->
(Model "" messages, WebSocket.send echoServer input)
NewMessage str ->
(Model input (str :: messages), Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen echoServer NewMessage
-- VIEW
view : Model -> Html Msg
view model =
div []
[ input [onInput Input, value model.input] []
, button [onClick Send] [text "Send"]
, div [] (List.map viewMessage (List.reverse model.messages))
]
viewMessage : String -> Html msg
viewMessage msg =
div [] [ text msg ]
Step 3 - Installa il pacchetto websocket usando il gestore di pacchetti elm.
C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket
Step 4 - Costruisci e genera il file index.html come mostrato di seguito.
C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm
Step 5 - Al momento dell'esecuzione, verrà generato il seguente output: