Elm - Hướng dẫn nhanh

Elm là một ngôn ngữ lập trình chức năng. Nó được thiết kế bởi Evan Czaplicki vào năm 2012.

Elm được sử dụng đặc biệt để thiết kế giao diện người dùng của các ứng dụng web.

Elm biên dịch sang JavaScript và chạy trong trình duyệt. Nó nhanh, có thể kiểm tra, có thể bảo trì và không có ngoại lệ Runtime.

Một số ứng dụng thực tế của nền tảng lập trình Elm bao gồm:

  • Games
  • Graphics
  • Ứng dụng trang đơn

Tại sao Elm

Elm loại bỏ hầu hết các vấn đề phổ biến mà các nhà phát triển frontend gặp phải. Điều này bao gồm -

Không có ngoại lệ thời gian chạy

Elm là một ngôn ngữ được gõ tĩnh. Tất cả các lỗi có thể xảy ra đều được xác nhận và sửa chữa tại thời điểm biên dịch. Điều này làm cho nó có thể không có ngoại lệ thời gian chạy.

Thông báo lỗi thân thiện với nhà phát triển

Không giống như các ngôn ngữ lập trình khác, trình biên dịch của Elm được thiết kế để cung cấp các thông báo lỗi rất cụ thể và thân thiện với nhà phát triển tại thời điểm biên dịch. Các thông báo lỗi cũng bao gồm các gợi ý như liên kết đến các tài liệu thiết kế được đề xuất.

Dễ dàng kiểm tra

Mỗi chức năng Elm có thể được kiểm tra riêng biệt với tất cả các chức năng khác. Điều này làm cho các chương trình được viết bằng Elm có thể dễ dàng kiểm tra.

Phiên bản ngữ nghĩa tự động

Elm thực thi lập phiên bản ngữ nghĩa tự động của các gói. Điều này đảm bảo rằng một thay đổi bản vá không làm hỏng một ứng dụng đã chạy.

Mã có thể tái sử dụng

Các hàm Elm vốn dĩ rất dễ sử dụng lại so với các hàm trong JavaScript, Python hoặc TypeScript.

Chương này thảo luận về các bước cài đặt Elm trên các nền tảng Windows, Mac và Linux.

Thiết lập môi trường cục bộ

Hãy xem xét các bước hiển thị bên dưới để cài đặt Elm trong môi trường cục bộ của bạn.

Step 1 − Install node

Vì cây du được biên dịch sang JavaScript nên máy đích phải có nodeCài đặt. Tham khảo khóa học TutorialsPoint NodeJS để biết các bước thiết lậpnodenpm

Thiết lập nút.

Step 2 − Install elm

Thực hiện lệnh sau trên thiết bị đầu cuối để cài đặt elm. Lưu ý rằng phiên bản ổn định của cây du là 0,18 tại thời điểm viết khóa học này.

npm install -g [email protected]

Sau khi cài đặt, hãy thực hiện lệnh sau để xác minh phiên bản của Elm.

C:\Users\dell>elm --version
0.18.0

Step 2 − Install the Editor

Môi trường phát triển được sử dụng ở đây là Visual Studio Code (nền tảng Windows).

Visual Studio Code là một IDE mã nguồn mở từ Visual Studio. Nó có sẵn cho các nền tảng Mac OS X, Linux và Windows. VSCode có sẵn tại

Cài đặt trên Windows

Trong phần này, chúng ta sẽ thảo luận về các bước cài đặt Elm trên Windows.

Tải xuống https://code.visualstudio.com/. cho cửa sổ.

Nhấp đúp vào VSCodeSetup.exe để khởi chạy quá trình thiết lập. Điều này sẽ chỉ mất một phút.

Bạn có thể truy cập trực tiếp vào đường dẫn của tệp bằng cách nhấp chuột phải vào Tệp → Mở trong dấu nhắc lệnh. Tương tự, tùy chọn Reveal in Explorer hiển thị tệp trong File Explorer.

Cài đặt trên Mac OS X

Hướng dẫn cài đặt cụ thể cho Mac OS X của Visual Studio Code có tại Cài đặt VSCode-MAC.

Cài đặt trên Linux

Hướng dẫn cài đặt cụ thể cho Linux của Visual Studio Code có thể được tìm thấy tại Cài đặt VSCode-Linux.

Step 4 − Install the elm Extension

Cài đặt phần mở rộng cây du trong VSCode như hình dưới đây.

Elm REPL

REPL là viết tắt của Read Eval Print Loop. Nó đại diện cho một môi trường máy tính như bảng điều khiển Windows hoặc Unix / Linux shell nơi một lệnh được nhập vào và hệ thống phản hồi với một đầu ra trong chế độ tương tác.

Elm đi kèm với một môi trường REPL. Nó thực hiện các nhiệm vụ sau:

  • Đọc - Đọc đầu vào của người dùng, phân tích cú pháp đầu vào thành cấu trúc dữ liệu elm và lưu trữ trong bộ nhớ.

  • Eval - Kiểm tra và đánh giá cấu trúc dữ liệu.

  • In - In kết quả.

  • Loop - Lặp lại lệnh trên cho đến khi người dùng thoát. Sử dụng lệnh: exit để thoát REPL và quay trở lại thiết bị đầu cuối.

Dưới đây là một ví dụ đơn giản để thêm hai số trong REPL:

Mở thiết bị đầu cuối VSCode và nhập lệnh elm REPL.

Thiết bị đầu cuối REPL chờ người dùng nhập một số đầu vào. Nhập biểu thức sau 10 + 20. Môi trường REPL xử lý đầu vào như cho bên dưới:

  • Đọc số 10 và 20 từ người dùng.

  • Đánh giá bằng cách sử dụng toán tử +.

  • Kết quả in là 30.

  • Vòng lặp cho lần nhập tiếp theo của người dùng. Ở đây chúng tôi thoát khỏi vòng lặp.

Chương này thảo luận về cách viết một chương trình đơn giản bằng cây du.

Step 1 − Create a directory HelloApp in VSCode

Bây giờ, hãy tạo một tệp - Hello.elm trong thư mục này.

Sơ đồ trên hiển thị thư mục dự án HelloApp và thiết bị đầu cuối được mở trong VSCode.

Step 2 − Install the necessary elm packages

Trình quản lý gói trong cây du là elm-package . Cài đặt gói elm-lang / html . Gói này sẽ giúp chúng tôi hiển thị đầu ra của mã cây du trong trình duyệt.

Đi ngang đến HelloApp thư mục dự án bằng cách nhấp chuột phải vào Tệp → Mở trong dấu nhắc lệnh trong VSCode.

Thực hiện lệnh sau trong cửa sổ dòng lệnh:

C:\Users\dell\Elm\HelloApp> elm-package install elm-lang/html

Các tệp / thư mục sau được thêm vào thư mục dự án khi cài đặt gói.

  • elm-package.json (tệp), lưu trữ dữ liệu meta của dự án
  • elm-things (thư mục), lưu trữ các gói bên ngoài

Thông báo sau sẽ xuất hiện khi gói được cài đặt thành công.

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"

Chương trình trên sẽ hiển thị thông báo chuỗi Hello Elm from TutorialsPoint trong trình duyệt.

Đối với điều này, chúng ta cần nhập hàm text trong Htmlmô-đun. Hàm văn bản được sử dụng để in bất kỳ giá trị chuỗi nào trong trình duyệt. Phương thức chính là điểm vào chương trình. Các chính phương pháp gọi các văn bản chức năng và vượt qua một giá trị chuỗi với nó.

Step 4 − Compile the project

Thực hiện lệnh sau trong cửa sổ VSCode terminal.

elm make Hello.elm

Đầu ra của lệnh trên như hình dưới đây:

//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

Lệnh trên sẽ tạo ra một index.htmltập tin. Trình biên dịch cây du chuyển đổi tệp .elm thành JavaScript và nhúng nó vàoindex.html tập tin.

Step 5 − Open the index.html in the browser

Mở tệp index.html trong bất kỳ trình duyệt nào. Đầu ra sẽ như hình dưới đây -

Nhận xét trong Elm

Nhận xét là một cách để cải thiện khả năng đọc của chương trình. Nhận xét có thể được sử dụng để bao gồm thông tin bổ sung về một chương trình như tác giả của mã, gợi ý về cấu trúc hàm, v.v. Nhận xét bị trình biên dịch bỏ qua.

Elm hỗ trợ các loại nhận xét sau:

  • Nhận xét một dòng (-) - Bất kỳ văn bản nào giữa dấu - và cuối dòng đều được coi là nhận xét.

  • Nhận xét nhiều dòng ({- -}) - Những nhận xét này có thể kéo dài nhiều dòng.

Hình minh họa

-- this is single line comment

{- This is a
   Multi-line comment
-}

Dòng và thụt lề

Elm không cung cấp dấu ngoặc nhọn để chỉ ra các khối mã cho các định nghĩa hàm hoặc điều khiển luồng. Các khối mã được biểu thị bằng cách thụt lề dòng, được thực thi nghiêm ngặt. Tất cả các câu lệnh trong một khối phải được thụt lề giống nhau. Ví dụ -

module ModuleIf exposing (..)
x = 0

function1 =
   if x > 5 then
      "x is greater"
   else
      "x is small"

Tuy nhiên, khối sau tạo ra lỗi:

-- 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"

Do đó, trong Elm, tất cả các dòng liên tục được thụt vào với cùng một số khoảng trắng sẽ tạo thành một khối.

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

Hệ thống Loại biểu thị các loại giá trị khác nhau được ngôn ngữ hỗ trợ. Hệ thống Loại kiểm tra tính hợp lệ của các giá trị được cung cấp trước khi chúng được chương trình lưu trữ hoặc thao tác. Điều này đảm bảo rằng mã hoạt động như mong đợi. Hệ thống Loại cũng cho phép gợi ý mã phong phú hơn và tài liệu tự động.

Elm là một ngôn ngữ được gõ tĩnh. Elm có các loại tương tự như từ các ngôn ngữ khác.

Con số

Các số kiểu dữ liệu đại diện cho các giá trị số. Hệ thống kiểu Elm hỗ trợ các kiểu số sau:

Sơ không. Kiểu Thí dụ
1 số - Lưu trữ bất kỳ số nào 7 là loại số
2 Float - Lưu trữ giá trị phân số 7/2 cho kết quả 3,5 là Float
3 Int - Lưu trữ các giá trị phi phân số 7 // 2 cho kết quả 3 là Int

Loại số chứa cả hai giá trị phân đoạn và không phân đoạn. Mở REPL của cây du và thử các ví dụ dưới đây:

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
>

Chuỗi và Char

Kiểu dữ liệu Chuỗi được sử dụng để biểu diễn một chuỗi ký tự. Kiểu dữ liệu Char được sử dụng để đại diện cho một ký tự. Giá trị chuỗi được xác định trong một dấu ngoặc kép "và các giá trị Char được đặt trong một dấu ngoặc kép" .

Sơ không. Kiểu Thí dụ
1 Chuỗi - Lưu trữ một chuỗi ký tự "TutorialsPoint"
2 Char - Lưu trữ giá trị phân số 'T'

Mở REPL của cây du và thử các ví dụ dưới đây:

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

Kiểu dữ liệu Bool trong Elm chỉ hỗ trợ hai giá trị - Đúng và Sai. Từ khóa Bool được sử dụng để biểu thị giá trị Boolean.

Sơ không. Kiểu Thí dụ
1 Bool - Lưu trữ giá trị Đúng hoặc Sai 1 == 1 trả về True

Mở REPL của cây du và thử các ví dụ dưới đây:

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

Các loại tùy chỉnh

Elm hỗ trợ tạo kiểu do người dùng xác định. Ví dụ, hãy xem xét một ứng dụng thanh toán. Ứng dụng cần lưu trữ các phương thức thanh toán khác nhau - thẻ tín dụng, thẻ ghi nợ và ngân hàng trực tuyến. Điều này có thể đạt được bằng cách xác định một loại tùy chỉnh và giới hạn giá trị của nó ở ba phương thức thanh toán được chấp nhận.

Ví dụ sau đây cho thấy cách tạo một loại tùy chỉnh.

> 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

Trong ví dụ trên, chúng tôi đã tạo loại tùy chỉnh PaymentMode. Các biến Payment1 và Payment2 được gán cho các giá trị PaymentMode. Nếu giá trị được gán cho biến không khớp với bất kỳ giá trị nào được xác định bởi loại PaymentMode, ứng dụng sẽ tạo ra lỗi cú pháp.

Các loại dữ liệu có cấu trúc

Các kiểu dữ liệu có cấu trúc có thể được sử dụng để lưu nhiều giá trị trong một định dạng có cấu trúc. Elm hỗ trợ các kiểu dữ liệu có cấu trúc sau:

  • Tuple
  • List
  • Record
  • Record

Những điều này sẽ được thảo luận chi tiết trong các chương sắp tới.

Một biến, theo định nghĩa, là "một không gian được đặt tên trong bộ nhớ" để lưu trữ các giá trị. Nói cách khác, nó hoạt động như một vùng chứa các giá trị trong một chương trình. Một biến giúp các chương trình lưu trữ và thao tác các giá trị.

Các biến trong Elm được liên kết với một kiểu dữ liệu cụ thể. Kiểu dữ liệu xác định kích thước và cách bố trí bộ nhớ của biến, phạm vi giá trị có thể được lưu trữ trong bộ nhớ đó và tập hợp các thao tác có thể thực hiện trên biến.

Quy tắc đặt tên biến

Trong phần này, chúng ta sẽ tìm hiểu về Quy tắc đặt tên biến.

  • Tên biến có thể bao gồm các chữ cái, chữ số và ký tự gạch dưới.
  • Tên biến không được bắt đầu bằng chữ số. Nó phải bắt đầu bằng một chữ cái hoặc một dấu gạch dưới.
  • Chữ hoa và chữ thường khác nhau vì Elm có phân biệt chữ hoa chữ thường.

Khai báo biến trong Elm

Cú pháp kiểu để khai báo một biến trong Elm được đưa ra dưới đây:

Cú pháp 1

variable_name:data_type = value

Cú pháp “:” (được gọi là chú thích kiểu) được sử dụng để liên kết biến với một kiểu dữ liệu.

Cú pháp 2

variable_name = value-- no type specified

Kiểu dữ liệu là tùy chọn trong khi khai báo một biến trong Elm. Trong trường hợp này, kiểu dữ liệu của biến được suy ra từ giá trị được gán cho nó.

Hình minh họa

Ví dụ này sử dụng trình soạn thảo VSCode để viết một chương trình cây du và thực thi nó bằng cách sử dụng repl cây du.

Step 1 − Create a project folder - VariablesApp. Create a Variables.elm file in the project folder.

Thêm nội dung sau vào tệp.

module Variables exposing (..) //Define a module and expose all contents in the module
message:String -- type annotation
message = "Variables can have types in Elm"

Chương trình định nghĩa một biến mô-đun. Tên của mô-đun phải giống với tên của tệp chương trình cây du. Cú pháp (..) được sử dụng để hiển thị tất cả các thành phần trong mô-đun.

Chương trình khai báo một thông báo biến kiểu String .

Step 2 − Execute the program.

  • Nhập lệnh sau vào thiết bị đầu cuối VSCode để mở elm REPL.
elm repl
  • Thực hiện câu lệnh elm sau trong thiết bị đầu cuối 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
>

Hình minh họa

Sử dụng Elm REPL để thử ví dụ sau.

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

Ở đây, các biến công ty và vị trí là các biến Chuỗi và xếp hạng là một biến Float.

Elm REPL không hỗ trợ chú thích kiểu cho các biến. Ví dụ sau sẽ đưa ra một lỗi nếu kiểu dữ liệu được bao gồm trong khi khai báo một biến.

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.

Để chèn ngắt dòng trong khi sử dụng elm REPL, hãy sử dụng cú pháp \ như hình dưới đây -

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

Một toán tử xác định một số chức năng sẽ được thực hiện trên dữ liệu. Các giá trị mà toán tử làm việc được gọi là toán hạng. Hãy xem xét biểu thức sau

7 + 5 = 12

Ở đây, các giá trị 7, 5 và 12 là toán hạng, trong khi + và = là toán tử.

Các toán tử chính trong Elm có thể được phân loại là:

  • Arithmetic
  • Relational
  • Logical

Toán tử số học

Giả sử các giá trị trong biến a và b lần lượt là 7 và 2.

Hiển thị các ví dụ

Sơ không. Nhà điều hành Sự miêu tả Thí dụ
1 + (Bổ sung) trả về tổng của các toán hạng a + b là 9
2 - (Phép trừ) trả về sự khác biệt của các giá trị ab là 5
3 * (Phép nhân) trả về sản phẩm của các giá trị a * b là 14
4 / (Bộ phận Phao nổi) thực hiện phép toán chia và trả về một thương số float a / b là 3,5
5 // (Phân chia số nguyên) thực hiện phép chia và trả về một thương số nguyên a // b là 3
6 % (Mô-đun) thực hiện phép toán chia và trả về phần còn lại a% b là 1

Toán tử quan hệ

Toán tử quan hệ kiểm tra hoặc xác định kiểu quan hệ giữa hai thực thể. Các toán tử này được sử dụng để so sánh hai hoặc nhiều giá trị. Các toán tử quan hệ trả về một giá trị Boolean, nghĩa là đúng hoặc sai.

Giả sử giá trị của a là 10 và b là 20.

Hiển thị các ví dụ

Sơ không. Nhà điều hành Sự miêu tả Thí dụ
1 > Lớn hơn (a> b) là Sai
2 < Ít hơn (a <b) là Đúng
3 > = Lớn hơn hoặc bằng (a> = b) là Sai
4 <= Nhỏ hơn hoặc bằng (a <= b) là Đúng
5 == Bình đẳng (a == b) là sai
6 ! = Không công bằng (a! = b) là True

Các loại có thể so sánh

Các toán tử so sánh như> = hoặc <hoạt động với các kiểu so sánh. Chúng được định nghĩa là số, ký tự, chuỗi và danh sách, bộ giá trị. Các kiểu so sánh ở cả hai phía của toán tử phải giống nhau.

Sơ không. Loại có thể so sánh Thí dụ
1 con số 7> 2 cho Đúng
2 tính cách 'a' == 'b' là False
3 chuỗi "xin chào" == "xin chào" là True
4 tuple (1, "One") == (1, "One") cho True
5 danh sách [1,2] == [1,2] cho đúng

Mở REPL cây du và thử các ví dụ được hiển thị bên dưới -

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
>

Toán tử logic

Toán tử lôgic được sử dụng để kết hợp hai hoặc nhiều điều kiện. Các toán tử logic cũng trả về giá trị Boolean.

Hiển thị các ví dụ

Sơ không. Nhà điều hành Sự miêu tả Thí dụ
1 && Toán tử chỉ trả về true nếu tất cả các biểu thức được chỉ định trả về true (10> 5) && (20> 5) trả về True
2 || Toán tử trả về true nếu ít nhất một trong các biểu thức được chỉ định trả về true (10 <5) || (20> 5) trả về True
3 không phải Toán tử trả về nghịch đảo của kết quả của biểu thức. Ví dụ:! (> 5) trả về false. not (10 <5) trả về True
4 xor Toán tử chỉ trả về true nếu chính xác một đầu vào trả về true. Toán tử trả về false nếu cả hai biểu thức đều trả về true. xor (10> 5) (20> 5) trả về false

Cấu trúc ra quyết định yêu cầu người lập trình chỉ định một hoặc nhiều điều kiện để được đánh giá hoặc kiểm tra bởi chương trình, cùng với một câu lệnh hoặc các câu lệnh sẽ được thực thi nếu điều kiện đó được xác định là đúng và tùy chọn, các câu lệnh khác sẽ được thực thi nếu điều kiện được xác định là sai.

Hình dưới đây là dạng chung của cấu trúc ra quyết định điển hình được tìm thấy trong hầu hết các ngôn ngữ lập trình

Một cấu trúc ra quyết định đánh giá một điều kiện trước khi các lệnh được thực thi. Các cấu trúc ra quyết định trong Elm được phân loại như sau:

Sơ không. Tuyên bố Sự miêu tả
1 câu lệnh if ... then ... else Câu lệnh if bao gồm một biểu thức Boolean theo sau là then được thực thi nếu biểu thức trả về true và else được thực thi nếu biểu thức trả về false
2 câu lệnh if lồng nhau Bạn có thể sử dụng một if ... then ... else bên trong if khác.
3 tuyên bố trường hợp Kiểm tra giá trị của một biến với danh sách các giá trị.

if ... then ... else Câu lệnh

Các if…thenconstruct đánh giá một điều kiện trước khi một khối mã được thực thi. Nếu biểu thức Boolean đánh giá là true, thì khối mã bên trong câu lệnh then sẽ được thực thi. Nếu biểu thức Boolean được đánh giá là false, thì khối mã bên trong câu lệnh else sẽ được thực thi.

Không giống như các ngôn ngữ lập trình khác, trong Elm chúng ta phải cung cấp nhánh else. Nếu không, Elm sẽ báo lỗi.

Cú pháp

if boolean_expression then statement1_ifTrue else statement2_ifFalse

Hình minh họa

Hãy thử ví dụ sau trong thiết bị đầu cuối REPL.

> if 10>5 then "10 is bigger" else "10 is small"
"10 is bigger" : String

Lồng nhau nếu

Câu lệnh if lồng nhau rất hữu ích để kiểm tra nhiều điều kiện. Cú pháp của câu lệnh if lồng nhau được đưa ra dưới đây:

if boolean_expression1 then statement1_ifTrue else if boolean_expression2 then statement2_ifTrue else statement3_ifFalse

Hình minh họa

Hãy thử ví dụ sau trong Elm REPL -

> score=80
80 : number
> if score>=80 then "Outstanding" else if score > = 70 then "good" else "average"
"Outstanding" : String

Tuyên bố tình huống

Câu lệnh case có thể được sử dụng để đơn giản hóa câu lệnh if then else. Cú pháp của một câu lệnh trường hợp như dưới đây:

case variable_name of
   constant1 -> Return_some_value
   constant2 -> Return_some_value
   _ -> Return_some_value if none of the above values match

Câu lệnh case kiểm tra xem giá trị của một biến có khớp với một tập hợp hằng số được xác định trước hay không và trả về giá trị tương ứng. Lưu ý rằng giá trị trả về của mỗi trường hợp phải cùng loại. Nếu giá trị của biến không khớp với bất kỳ hằng nào đã cho, thì điều khiển được chuyển đến * default * (ký hiệu là // _) và giá trị tương ứng được trả về.

Hình minh họa

Hãy thử ví dụ sau trong Elm REPL -

> n = 10
10 : number
> case n of \
| 0 -> "n is Zero" \
| _ -> "n is not Zero"
"n is not Zero" : String

Đoạn mã trên kiểm tra xem giá trị của n có bằng 0 hay không. Điều khiển được chuyển thành mặc định, trả về chuỗi “n không phải là 0”.

Elm là một ngôn ngữ lập trình chức năng. Elm sử dụng khái niệm đệ quy để thay thế cho các cấu trúc lặp truyền thống.

Chương này thảo luận về khái niệm đệ quy.

Đệ quy

Một số ngôn ngữ lập trình máy tính cho phép một mô-đun hoặc hàm gọi chính nó. Kỹ thuật này được gọi là đệ quy.

Hình minh họa

Trong chương trình này, chúng ta sẽ xem cách sử dụng đệ quy để hiển thị lời chào năm lần.

Step 1 − Create a file Loop.elm

Tạo vòng lặp mô-đun và xác định một chức năng sayHello. Hàm sayHello nhận một giá trị nguyên làm đầu vào và trả về một giá trị chuỗi.

module Loop exposing(..)
//function signature
sayHello:Int ->String
//function implementation
sayHello n =
   case n of
   1 -> "Hello:1 "
   _ -> "Hello:" ++ toString (n) ++ " " ++ sayHello(n-1)

Hàm sayHello kiểm tra nếu tham số được truyền là 1. Nếu tham số là 1, thì hàm sẽ trả về, nếu không nó sẽ tạo một chuỗi Hello và gọi hàm tương tự.

Step 2 − Invoke sayHello from REPL

Mở REPL cây du từ thư mục dự án hiện tại (vị trí của tệp Loop.elm).

//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
>

Hình minh họa

Ví dụ sau in ra tổng của n số bằng cách sử dụng đệ quy.

> sumOfNos n =\
| if n==0 then 0 \
| else (n) + sumOfNos (n-1)
<function> : number -> number1

Trong elm REPL, chúng tôi đã tạo một hàm sumOfNos nhận một số đầu vào và tính tổng tất cả các số từ 0 đến số đó.

Ví dụ: nếu chúng ta chuyển đầu vào là 5, nó sẽ tổng 1 + 2 + 3 + 4 + 515 .

> ssumOfNos 5
15 : number

Kết quả của chương trình được hiển thị ở trên.

Các hàm là các khối xây dựng của một chương trình Elm. Hàm là một tập hợp các câu lệnh để thực hiện một nhiệm vụ cụ thể.

Các hàm tổ chức chương trình thành các khối mã logic. Sau khi được xác định, các hàm có thể được gọi để truy cập mã. Điều này làm cho mã có thể được sử dụng lại. Hơn nữa, các hàm giúp bạn dễ dàng đọc và duy trì mã của chương trình.

Các bước sử dụng một hàm

Có ba bước để sử dụng một hàm:

Khai báo hàm

Một khai báo hàm cho trình biên dịch biết về tên, kiểu trả về và các tham số của hàm. Cú pháp để khai báo một hàm được đưa ra dưới đây:

fn_name:data_type_of_the_parameters ->return_type

Khai báo hàm chỉ định như sau:

  • Tên của hàm.

  • Kiểu dữ liệu của các tham số. Đây là tùy chọn vì một hàm có thể có hoặc không có tham số.

  • Kiểu dữ liệu của giá trị mà hàm sẽ trả về. Các hàm trong Elm phải luôn trả về một giá trị vì Elm là một ngôn ngữ lập trình hàm. Không giống như các hàm trong các ngôn ngữ lập trình khác, các hàm Elm không sử dụng từ khóa return để trả về một giá trị.

Định nghĩa chức năng hoặc thực hiện chức năng

Một định nghĩa hàm cung cấp nội dung thực tế của hàm. Một định nghĩa hàm chỉ định cách một nhiệm vụ cụ thể sẽ được thực hiện. Cú pháp để xác định một hàm như dưới đây:

fn_name parameter1 parameter2 = statements

Gọi hoặc gọi một chức năng

Một hàm phải được gọi để thực thi nó. Cú pháp để gọi một hàm được đưa ra dưới đây:

fn_name parameter1 parameter2

Hình minh họa

Đoạn mã sau định nghĩa một hàm chào. Hàm trả về một chuỗi "Hello".

> greet = \
| if True then \
| "Hello" \
| else \
| "GoodBye"
"Hello" : String
> greet
"Hello" : String

Các chức năng được tham số hóa

Tham số là một cơ chế để truyền các giá trị cho một hàm. Giá trị của các tham số được chuyển cho hàm tại thời điểm gọi hàm.

Minh họa 1

Ví dụ sau định nghĩa một hàm fn_add . Hàm nhận hai số làm tham số và trả về tổng của chúng. Hãy thử những điều sau đây trong elm REPL -

> fn_add x y = x+y
<function> : number -> number -> number
> fn_add 10 20
30 : number

Minh họa 2

Ví dụ sau định nghĩa một hàm sayHello. Hàm sayHello chấp nhận và trả về một giá trị Chuỗi làm tham số và trả về một Chuỗi.

> sayHello name = "Hello "++ name
<function> : String -> String
> sayHello "Tutorialspoint"
"Hello Tutorialspoint" : String
>

Nhà điều hành đường ống

Để hiểu toán tử pipe |>, chúng ta hãy xem xét một ví dụ trong đó chúng ta có một danh sách các chuỗi khác nhau ["a", "b", "c"] . Bây giờ chúng ta cần một chuỗi đơn, được phân tách bằng -

Ví dụ sau đây cho thấy cách thực hiện điều đó với String.join

> String.join "-" ["a","b","c","d","e","f"]
"a-b-c-d-e-f" : String

Hành động tương tự có thể được thực hiện bằng cách sử dụng toán tử ống |>. Toán tử đường ống có thể được sử dụng để xâu chuỗi nhiều lệnh gọi hàm.

> ["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

Trong ví dụ đầu tiên, chúng ta đang xâu chuỗi danh sách để tham gia phương thức. Trong trường hợp thứ hai, danh sách tương tự được chuyển sang chức năng đảo ngược và sau đó được chuyển sang tham gia. Vì vậy, danh sách được hiển thị trong đảo ngược và nối.

Một chuỗi các ký tự Unicode được gọi là một Chuỗi. Trong Elm, các chuỗi được đặt trong dấu ngoặc kép "" . Chuỗi là một đoạn văn bản như hình dưới đây.

> "TutorialsPoint"
"TutorialsPoint" : String
> location = "Hyderabad" --variable
"Hyderabad" : String
> location
"Hyderabad" : String
>

Hàm chuỗi

Một số hàm phổ biến có thể được sử dụng để truy vấn hoặc thao tác các giá trị chuỗi được đưa ra dưới đây. Sử dụng REPL để thử các ví dụ dưới đây.

Sơ không phương pháp Sự miêu tả
1 isEmpty: String -> Bool chuỗi kiểm tra trống
2 đảo ngược: Chuỗi -> Chuỗi đảo ngược một chuỗi đầu vào
3 chiều dài: String -> Int trả về độ dài số nguyên
4 nối thêm: Chuỗi -> Chuỗi -> Chuỗi nối hai chuỗi và trả về một chuỗi mới
5 append: String -> Sconcat: List String -> String nối một danh sách các chuỗi và trả về một chuỗi mới
6 split: String -> String -> List String tách một chuỗi đầu vào bằng cách sử dụng một dấu phân tách đã cho, trả về một danh sách chuỗi
7 lát cắt: Int -> Int -> String -> String trả về một chuỗi con cho trước một chỉ mục bắt đầu, kết thúc và chuỗi đầu vào
số 8 chứa: Chuỗi -> Chuỗi -> Bool trả về true nếu chuỗi thứ hai chứa chuỗi thứ nhất
9 toInt: String -> Result.Result String Int phân tích cú pháp một chuỗi thành số nguyên
10 toInt: String -> Result.Result String Int phân tích cú pháp một chuỗi thành số nguyên
11 toFloat: String -> Result.Result String Float phân tích cú pháp một chuỗi để thả nổi
12 fromChar: Char -> String tạo một chuỗi từ một ký tự nhất định.
13 toList: String -> List Char chuyển đổi chuỗi thành danh sách các ký tự
14 fromList: Danh sách Char -> Chuỗi chuyển đổi danh sách các ký tự thành một chuỗi
15 toUpper: String -> String chuyển chuỗi đầu vào thành chữ hoa
16 trim: Chuỗi -> Chuỗi loại bỏ khoảng trắng trên cả hai mặt của một chuỗi.
17 bộ lọc: (Char -> Bool) -> String -> String bộ lọc bộ ký tự từ chuỗi đầu vào
18 bản đồ: (Char -> Char) -> String -> String biến đổi mọi ký tự trong một chuỗi đầu vào

isEmpty

Hàm này có thể được sử dụng để xác định xem một chuỗi có trống hay không. Hàm này trả về True nếu Chuỗi được cung cấp trống.

Cú pháp

String.isEmpty String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.isEmpty
<function> : String -> Bool

Chữ ký của hàm hiển thị Bool là kiểu trả về và kiểu đầu vào là Chuỗi -

Hình minh họa

> String.isEmpty ""
True : Bool
> String.isEmpty "Tutorialspoint"
False : Bool
> location = "Hyderabad"
"Hyderabad" : String
> String.isEmpty location
False : Bool

đảo ngược

Hàm này đảo ngược một chuỗi.

Cú pháp

String.reverse String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.reverse
<function> : String -> String

Chữ ký của hàm hiển thị Chuỗi là kiểu trả về và kiểu đầu vào là Chuỗi -

Hình minh họa

> String.reverse "TutorialsPoint"
"tnioPslairotuT" : String

chiều dài

Hàm này trả về độ dài của một chuỗi.

Cú pháp

String.length String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.length
<function-> : String -> Int

Chữ ký của hàm hiển thị Int là kiểu trả về và kiểu đầu vào là Chuỗi.

Hình minh họa

> String.length "Mohtashim"
9 : Int

nối thêm

Hàm này trả về một chuỗi mới bằng cách nối hai chuỗi.

Cú pháp

String.append String_value1 String_value2

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.append
<function-> : String -> String -> String

Chữ ký của hiển thị hai tham số đầu vào Chuỗi và một tham số đầu ra chuỗi

Hình minh họa

> String.append "Tutorials" "Point"
TutorialsPoint : String

kết hợp

Hàm này trả về một chuỗi mới bằng cách nối nhiều chuỗi thành một.

Cú pháp

String.concat [String1,String2,String3]

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.concat
<function> : List String -> String

Chữ ký của hiển thị Danh sách tham số đầu vào Chuỗi và kiểu trả về Chuỗi

Hình minh họa

> String.concat ["Hello","Tutorials","Point"]
HelloTutorialsPoint : String

tách ra

Hàm này tách một chuỗi bằng dấu phân cách đã cho.

Cú pháp

String.split string_seperator String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.split
<function> : String -> String -> List String

Chữ ký của hiển thị hai tham số Chuỗi đầu vào và đầu ra dưới dạng danh sách kiểu chuỗi.

Hình minh họa

> String.split "," "Hello,Tutorials,Point"
["Hello","Tutorials","Point"] : List String

lát

Hàm này trả về một chuỗi con cho trước chỉ số bắt đầu và kết thúc. Chỉ mục âm được lấy bắt đầu từ cuối danh sách. Giá trị của chỉ mục bắt đầu từ số không.

Cú pháp

String.slice start_index end_index String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.slice
<function> : Int -> Int -> String -> String

Chữ ký của hiển thị ba tham số đầu vào và một kiểu trả về.

Hình minh họa

> String.slice 0 13 "TutorialsPoint"
"TutorialsPoin" : String

chứa đựng

Hàm này trả về giá trị True nếu chuỗi thứ hai chứa chuỗi thứ nhất.

Cú pháp

String.contains string1 string2

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.contains
<function> : String -> String -> Bool

Chữ ký của hiển thị kiểu trả về bool và hai tham số đầu vào

Hình minh họa

> String.contains "Point" "TutorialsPoint"
True : Bool

toInt

Hàm này chuyển đổi một chuỗi thành một int.

Cú pháp

String.toInt string_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.toInt
<function> : String -> Result.Result String Int

Vì toInt có thể trả về lỗi, kiểu trả về là Kết quả, là Chuỗi hoặc Int.

Hình minh họa

> 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

Hàm này chuyển đổi một chuỗi thành một float.

Cú pháp

String.toFloat string_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.toFloat
<function> : String -> Result.Result String Float

Vì toFloat có thể trả về lỗi, nên kiểu trả về là Kết quả, là Chuỗi hoặc Pha nổi.

Hình minh họa

> 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

Hàm này tạo một chuỗi từ một ký tự nhất định.

Cú pháp

String.fromChar character_value

Để kiểm tra chữ ký của loại hàm sau đây trong elm REPL -

> String.fromChar
<function> : Char -> String

Chữ ký hiển thị Chuỗi là kiểu trả về và đầu vào là kiểu Char

Hình minh họa

> String.fromChar 'c'
"c" : String

liệt kê

Hàm này chuyển đổi một chuỗi thành một danh sách các ký tự.

Cú pháp

String.toList string_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.toList
<function> : String -> List Char

Hàm hiển thị chữ ký trả về một danh sách các ký tự và nhận đầu vào một chuỗi.

Hình minh họa

> String.toList "tutorialspoint"
['t','u','t','o','r','i','a','l','s','p','o','i','n','t'] : List Char

fromList

Hàm này chuyển đổi một danh sách các ký tự thành một Chuỗi.

Cú pháp

String.fromList list_of_characters

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.fromList
<function> : List Char -> String

Hàm hiển thị chữ ký trả về một danh sách các ký tự và nhận đầu vào một chuỗi.

Hình minh họa

> String.fromList ['h','e','l','l','o']
"hello" : String

toUpper

Hàm này chuyển đổi một chuỗi thành tất cả các chữ hoa.

Cú pháp

String.toUpper String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.toUpper
<function> : String -> String

Hình minh họa

> String.toUpper "hello"
"HELLO" : String

toLower

Hàm này chuyển đổi một chuỗi thành tất cả các chữ thường.

Cú pháp

String.toLower String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.toLower
<function> : String -> String

Hình minh họa

> String.toLower "AbCd"
"abcd" : String

cắt tỉa

Hàm này loại bỏ khoảng trắng trên cả hai mặt của một chuỗi.

Cú pháp

String.trim String_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.trim
<function> : String -> String

Hình minh họa

> String.trim "tutorialspoint "
"tutorialspoint" : String

bộ lọc

Hàm này lọc một tập hợp các ký tự từ Chuỗi đầu vào. Chỉ giữ lại những ký tự vượt qua bài kiểm tra.

Cú pháp

String.filter test_function string_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.filter
<function> : (Char -> Bool) -> String -> String

Chữ ký cho thấy bộ lọc nhận hai tham số đầu vào và trả về một Chuỗi. Tham số đầu tiên là một hàm, có đầu vào Char và trả về Bool.

Hình minh họa

Trong ví dụ, chúng tôi đang chuyển Char.isUpper làm tham số cho phương thức lọc; nó trả về tất cả các ký tự viết hoa như hình dưới đây.

> import Char
> String.filter Char.isUpper "abcDEF"
"DEF" : String

bản đồ

Hàm này nhận một Chuỗi và biến đổi mọi ký tự trong một chuỗi.

Cú pháp

String.filter mapping_function string_value

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> String.map
<function> : (Char -> Char) -> String -> String

Hình minh họa

Ví dụ sau thay thế ký tự o bằng @ -

> String.map (\c -> if c == 'o' then '@' else c) "TutorialsPoint"
"Tut@rialsP@int" : String

Cấu trúc dữ liệu Danh sách, Tuples và Bản ghi có thể được sử dụng để lưu trữ một tập hợp các giá trị.

Chương này thảo luận về cách sử dụng Danh sách trong Elm.

Danh sách là một tập hợp các giá trị đồng nhất. Tất cả các giá trị trong danh sách phải thuộc cùng một kiểu dữ liệu.

Hãy xem xét các hạn chế sau khi sử dụng các biến để lưu trữ các giá trị:

  • Các biến có bản chất vô hướng. Nói cách khác, tại thời điểm khai báo, một biến chỉ có thể chứa một giá trị. Điều này có nghĩa là để lưu trữ n giá trị trong một chương trình, sẽ cần n khai báo biến. Do đó, việc sử dụng các biến là không khả thi khi một người cần lưu trữ một bộ sưu tập giá trị lớn hơn.

  • Các biến trong chương trình được cấp phát bộ nhớ theo thứ tự ngẫu nhiên, do đó gây khó khăn cho việc truy xuất / đọc các giá trị theo thứ tự khai báo của chúng.

Cú pháp

List_name = [value1,value2,value3.....valuen]

Hình minh họa

Ví dụ sau đây cho thấy cách sử dụng Danh sách trong Elm. Hãy thử ví dụ này trong elm REPL -

> myList1 = [10,20,30]
[10,20,30] : List number
> myList2 = ["hello","world"]
["hello","world"] : List String

Nếu chúng ta thử thêm các giá trị của các kiểu khác nhau vào một danh sách, trình biên dịch sẽ xuất hiện lỗi không khớp kiểu. Điều này được hiển thị bên dưới.

> 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

Liệt kê các hoạt động

Bảng sau đây cho thấy các thao tác phổ biến trên một Danh sách:

Sơ không phương pháp Sự miêu tả
1 isEmpty: Danh sách a -> Bool kiểm tra xem danh sách có trống không
2 đảo ngược: Liệt kê a -> Bool đảo ngược danh sách đầu vào
3 chiều dài: Danh sách a -> Int trả về kích thước của danh sách
4 tối đa: Có thể so sánh danh sách -> Có thể. Có thể so sánh trả về giá trị tối đa
5 tối thiểu: Danh sách có thể so sánh -> Có thể. Có thể có thể so sánh trả về giá trị tối thiểu
6 sum: Danh sách số -> số trả về tổng của tất cả các phần tử trong danh sách
7 sản phẩm: Số danh sách -> số kiểm tra xem danh sách có trống không
số 8 sắp xếp: Danh sách có thể so sánh -> Danh sách có thể so sánh sắp xếp danh sách theo thứ tự tăng dần
9 concat: Danh sách (Danh sách a) -> Danh sách a hợp nhất một loạt danh sách thành một
10 nối thêm: Liệt kê a -> Liệt kê a -> Liệt kê a hợp nhất hai danh sách với nhau
11 phạm vi: Int -> Int -> List Int trả về một danh sách các số từ đầu đến cuối
12 filter: (a -> Bool) -> List a -> List a lọc danh sách các giá trị từ danh sách đầu vào
13 head: Liệt kê a -> Có thể. Có thể a trả về phần tử đầu tiên từ danh sách
14 tail:: Liệt kê a -> Có thể.Maybe (Liệt kê a) trả về tất cả các phần tử ngoại trừ phần đầu

isEmpty

Hàm này trả về true nếu danh sách trống.

Cú pháp

List.isEmpty list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.isEmpty
<function> : List a -> Bool

Hình minh họa

> List.isEmpty
<function> : List a -> Bool

> List.isEmpty [10,20,30]
False : Bool

đảo ngược

Chức năng này đảo ngược danh sách.

Cú pháp

List.reverse list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.reverse
<function> : List a -> List a

Hình minh họa

> List.reverse [10,20,30]
[30,20,10] : List number

chiều dài

Hàm này trả về độ dài của một danh sách.

Cú pháp

List.length list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.length
<function> : List a -> Int

Hình minh họa

> List.length [10,20,30]
3 : Int

tối đa

Hàm này trả về phần tử tối đa trong danh sách không trống.

Cú pháp

List.maximum list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.maximum
<function> : List comparable -> Maybe.Maybe comparable

Hình minh họa

> List.maximum [10,20,30]
Just 30 : Maybe.Maybe number
> List.maximum []
Nothing : Maybe.Maybe comparable

tối thiểu

Hàm này trả về phần tử tối thiểu trong danh sách không trống.

Cú pháp

List.minimum list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.minimum
<function> : List comparable -> Maybe.Maybe comparable

Hình minh họa

> List.minimum [10,20,30]
Just 10 : Maybe.Maybe number

Tổng

Hàm này trả về tổng của tất cả các phần tử trong một danh sách.

Cú pháp

List.sum list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.sum
<function> : List number -> number

Hình minh họa

> List.sum [10,20,30]
60 : number

sản phẩm

Hàm này trả về tích của tất cả các phần tử trong danh sách.

Cú pháp

List.product list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

<function>  : List number ->  number

Hình minh họa

List.product [10,20,30]
6000 : number

sắp xếp

Hàm này sắp xếp các giá trị từ thấp nhất đến cao nhất trong một danh sách.

Cú pháp

List.sort list_name

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.sort
<function> : List comparable -> List comparable

Hình minh họa

> List.sort [10,20,30]
[10,20,30] : List number

kết hợp

Hàm này nối nhiều danh sách vào một danh sách.

Cú pháp

List.concat [ [list_name1],[list_name2],[list_name3],.....[list_nameN] ]

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.concat
<function> : List (List a) -> List a

Hình minh họa

> List.concat [[10,20], [30,40],[50,60]]
[10,20,30,40,50,60] : List number

nối thêm

Hàm này đặt hai danh sách lại với nhau.

Cú pháp

List.append [list_name1] [list_name2]

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.append
<function> : List a -> List a -> List a

Hình minh họa

> List.append [10,20] [30,40]
[10,20,30,40] : List number

Toán tử ++ cũng có thể được sử dụng để nối một danh sách vào một danh sách khác. Điều này được hiển thị trong ví dụ dưới đây -

> [10.1,20.2] ++ [30.3,40.4]
[10.1,20.2,30.3,40.4] : List Float

phạm vi

Hàm này tạo một danh sách các số, mỗi phần tử tăng lên một. Số thấp nhất và số cao nhất cần có trong danh sách được chuyển cho hàm.

Cú pháp

List.range start_range end_range

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.range
<function> : Int -> Int -> List Int

Hình minh họa

> List.range 1 10
[1,2,3,4,5,6,7,8,9,10] : List Int

bộ lọc

Hàm này lọc một tập hợp các giá trị từ danh sách đầu vào. Chỉ giữ lại các giá trị vượt qua bài kiểm tra.

Cú pháp

List.filter test_function input_list

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.filter
<function> : (a -> Bool) -> List a -> List a

Hình minh họa

Ví dụ sau lọc tất cả các số chẵn khỏi danh sách đầu vào

> List.filter (\n -> n%2==0) [10,20,30,55]
[10,20,30] : List Int

cái đầu

Hàm này trả về phần tử đầu tiên từ danh sách đầu vào.

Cú pháp

List.head input_list

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.head
<function> : List a -> Maybe.Maybe a

Hình minh họa

> List.head [10,20,30,40]
Just 10 : Maybe.Maybe number
> List.head []
Nothing : Maybe.Maybe a

đuôi

Hàm này trả về tất cả các phần tử sau phần tử đầu tiên trong danh sách.

Cú pháp

List.tail input_list

Để kiểm tra chữ ký của hàm, hãy nhập thông tin sau vào elm REPL -

> List.tail
<function> : List a -> Maybe.Maybe (List a)

Hình minh họa

> 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)

Sử dụng toán tử khuyết điểm

Toán tử khuyết điểm (::) thêm một phần tử vào đầu danh sách.

Hình minh họa

> 10::[20,30,40,50]
[10,20,30,40,50] : List number

Phần tử mới sẽ được thêm vào và kiểu dữ liệu của các giá trị trong danh sách phải khớp. Trình biên dịch sẽ báo lỗi nếu các kiểu dữ liệu không khớp.

> [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.

Danh sách là bất biến

Hãy để chúng tôi kiểm tra xem danh sách có bất biến trong Elm không. Danh sách myList đầu tiên khi được nối với giá trị 1 sẽ tạo ra một danh sách mới và được trả về myListCopy . Do đó, nếu chúng ta hiển thị danh sách ban đầu, các giá trị của nó sẽ không bị thay đổi.

> 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

Đôi khi, có thể cần phải lưu trữ một bộ sưu tập các giá trị thuộc nhiều loại khác nhau. Elm cung cấp cho chúng ta một cấu trúc dữ liệu được gọi là tuple phục vụ mục đích này.

Một bộ giá trị đại diện cho một tập hợp các giá trị không đồng nhất. Nói cách khác, bộ giá trị cho phép lưu trữ nhiều trường thuộc các loại khác nhau. Một bộ lưu trữ số lượng giá trị cố định. Tuples hữu ích khi bạn muốn trả về nhiều giá trị thuộc các kiểu khác nhau từ một hàm. Các cấu trúc dữ liệu này là bất biến giống như các kiểu khác trong cây du.

Cú pháp

(data1,data2)

Một ví dụ đơn giản được hiển thị bên dưới:

> ("TuotrialsPoint",5,True,"Hyderabad")
("TuotrialsPoint",5,True,"Hyderabad") : ( String, number, Bool, String )

Trong các phần tiếp theo, chúng ta sẽ tìm hiểu về các hoạt động tuple khác nhau.

Đầu tiên

Thao tác này trích xuất giá trị đầu tiên từ một bộ giá trị.

Cú pháp

Tuple.first tuple_name
> Tuple.first
<function> : ( a1, a2 ) -> a1

Hình minh họa

> Tuple.first (10,"hello")
10 : number

thứ hai

Các second hoạt động tuple trích xuất giá trị thứ hai từ một tuple.

Cú pháp

Tuple.second tuple_name
> Tuple.second
<function> : ( a1, a2 ) -> a2

Hình minh họa

> Tuple.second (10,"hello")
"hello" : String

Danh sách các bộ giá trị

Danh sách có thể lưu trữ Tuples. Nếu các bộ giá trị được sử dụng bên trong một danh sách, hãy đảm bảo rằng tất cả chúng đều có cùng kiểu dữ liệu và có cùng số lượng tham số.

Hình minh họa

> [("hello",20),("world",30)]
[("hello",20),("world",30)] : List ( String, number )

Tuple với chức năng

Một hàm có thể trả về các bộ giá trị. Ngoài ra, các bộ giá trị có thể được chuyển làm tham số cho các hàm.

Minh họa 1

Ví dụ sau định nghĩa một hàm fn_checkEven. Hàm này nhận một giá trị số nguyên làm tham số và trả về một bộ giá trị.

> 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 )
>

Minh họa 2

Phần sau chuyển một tuple làm tham số cho một hàm.

> fn_add (a,b) = \
| a+b
<function> : ( number, number ) -> number
> fn_add (10,20)
30 : number

Hàm fn_add nhận một bộ giá trị có 2 giá trị số và trả về tổng của chúng.

Phá hủy

Việc phá hủy liên quan đến việc chia nhỏ một bộ giá trị thành các giá trị riêng lẻ. Để truy cập các giá trị riêng lẻ trong một bộ có ba phần tử trở lên, chúng tôi sử dụng cấu trúc hủy. Ở đây, chúng tôi gán từng giá trị trong một bộ giá trị cho các biến khác nhau. Sử dụng _ người ta có thể xác định trình giữ chỗ cho các giá trị sẽ bị bỏ qua hoặc bỏ qua.

Hình minh họa

> (first,_,_) = (10,20,30)
10 : number
> first
10 : number

Hình minh họa

Trong ví dụ này, chúng tôi sẽ sử dụng cú pháp khối let..in để cấu trúc lại. Khối let chứa các biến và khối in chứa các biểu thức cần được đánh giá và giá trị sẽ được trả về.

> t1 = (10,20,30)
(10,20,30) : ( number, number1, number2 )
> let \
(a,b,c) = t1 \
in\
a + b +c
60 : number

Chúng tôi đang khai báo các biến abc trong mệnh đề let và truy cập chúng bằng cách sử dụng trong mệnh đề.

Cấu trúc dữ liệu bản ghi trong Elm có thể được sử dụng để biểu diễn dữ liệu dưới dạng các cặp khóa-giá trị. Một bản ghi có thể được sử dụng để sắp xếp dữ liệu liên quan để cho phép dễ dàng truy cập và cập nhật dữ liệu. Bản ghi Elm tương tự như các đối tượng trong JavaScript. Các phần tử dữ liệu trong một bản ghi được gọi là trường.

Xác định bản ghi

Sử dụng cú pháp sau để xác định một bản ghi:

Cú pháp

record_name = {fieldname1 = value1, fieldname2 = value2....fieldnameN = valueN}

Một bản ghi có thể lưu trữ dữ liệu của nhiều loại. Các tên trường trong bản ghi phải tuân theo các quy tắc chung để đặt tên cho một số nhận dạng Elm.

Truy cập các giá trị bản ghi

Sử dụng cú pháp sau để truy cập các trường riêng lẻ trong một bản ghi.

Cú pháp

record_name.fieldname

HOẶC LÀ

.fieldname record_name

Hình minh họa

Hãy thử những điều sau đây trong 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

Sử dụng Bản ghi với Danh sách

Một bản ghi có thể được lưu trữ bên trong một danh sách. Tất cả các giá trị trường của bản ghi phải cùng loại.

Cú pháp

list_name = [ {field_name1 = value1},{field_name1 = value2}]

HOẶC LÀ

list_name = [record_name1, record_name2, record_name3....record_nameN]

Hình minh họa

Hãy thử những điều sau trong 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 }

Cập nhật bản ghi

Các bản ghi là bất biến trong Elm. Khi một bản ghi được cập nhật, một bản ghi mới với các giá trị được cập nhật sẽ được trả về. Trường có thể giữ giá trị của một kiểu khác khi cập nhật bản ghi.

Cú pháp

{record_name | field_name1 = new_value1, field_name2 = new_value2,field_name3 = new_value3....field_nameN = new_valueN}

Hình minh họa

Hãy thử những điều sau trong 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

Hình minh họa

Ví dụ sau cập nhật nhiều trường của một bản ghi. Hãy thử những điều sau trong 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 }
>

Các loại bí danh

Loại bí danh xác định một lược đồ cho một bản ghi. Nói cách khác, bí danh kiểu xác định trường nào có thể lưu trữ bản ghi và kiểu giá trị mà các trường này có thể lưu trữ. Do đó, lập trình viên sẽ không mắc lỗi thiếu bất kỳ thuộc tính cụ thể nào trong khi gán giá trị.

Cú pháp

type alias alias_name = {field_name1:data_type,field_name2:data_type,....field_nameN:data_type}

Hình minh họa

Thực hiện những điều sau trong 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
>

Bây giờ nếu bạn quên nhập vị trí và tuổi, câu lệnh sẽ trả về một hàm, có các tham số đầu vào cho các trường vị trí và tuổi.

> 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

Lỗi là bất kỳ điều kiện không mong muốn nào trong một chương trình. Lỗi có thể xảy ra ở thời gian biên dịch hoặc thời gian chạy. Lỗi thời gian biên dịch xảy ra trong quá trình biên dịch chương trình (Ví dụ: lỗi trong cú pháp của chương trình) trong khi lỗi thời gian chạy xảy ra trong quá trình thực thi chương trình. Không giống như các ngôn ngữ lập trình khác, Elm không gây ra lỗi thời gian chạy.

Xem xét một ứng dụng chấp nhận độ tuổi của người dùng. Ứng dụng sẽ thông báo lỗi nếu tuổi bằng 0 hoặc âm. Trong trường hợp này, ứng dụng Elm có thể sử dụng khái niệm xử lý lỗi để đưa ra lỗi rõ ràng trong thời gian chạy nếu người dùng nhập giá trị 0 hoặc giá trị âm là tuổi. Xử lý lỗi chỉ định quá trình hành động nếu có bất kỳ điều gì không mong muốn xảy ra trong quá trình thực thi chương trình.

Ngôn ngữ lập trình Elm xử lý lỗi theo những cách sau:

  • MayBe
  • Result

Có lẽ

Xem xét tính năng tìm kiếm trong một ứng dụng. Chức năng tìm kiếm trả về dữ liệu liên quan nếu từ khóa tìm kiếm được tìm thấy khác không trả về bất kỳ thứ gì. Trường hợp sử dụng này có thể được thực hiện trong Elm bằng cách sử dụng kiểu MayBe.

Cú pháp

variable_name:MayBe data_type

Một biến kiểu MayBe có thể chứa một trong các giá trị sau:

  • Just some_Value - Điều này được sử dụng nếu có dữ liệu hợp lệ.

  • Không có gì - Điều này được sử dụng nếu giá trị không có hoặc không xác định. Không có gì tương đương với null trong các ngôn ngữ lập trình khác.

Hình minh họa

Ví dụ sau đây cho thấy cách sử dụng kiểu MayBe với các biến và hàm.

Step 1 - Tạo một MayBeDemo.elm tệp và thêm mã sau vào nó

-- 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 - Nhập mô-đun trong elm repl và thực thi như dưới đây

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 
      

Hàm kiểm tra xem giá trị được truyền vào hàm là Ấn Độ hay Trung Quốc hoặc SriLanka. Nếu giá trị của tham số không khớp với bất kỳ giá trị nào trong số này, nó sẽ không trả về giá trị nào.

Kết quả

Hãy xem xét một ví dụ, trong đó ứng dụng cần xác thực một số điều kiện và đưa ra lỗi nếu điều kiện không được thỏa mãn. Loại Kết quả có thể được sử dụng để đạt được điều này. Loại Kết quả nên được sử dụng nếu ứng dụng muốn nêu ra lỗi một cách rõ ràng và trả lại chi tiết về những gì đã xảy ra.

Cú pháp

Khai báo Kiểu kết quả nhận hai tham số - kiểu dữ liệu của lỗi (thường là Chuỗi) và kiểu dữ liệu của kết quả sẽ được trả về nếu mọi thứ diễn ra tốt đẹp.

type Result error_type data_value_type
= Ok data_value
| Err error_message

Loại Kết quả trả về một trong các giá trị sau:

  • Ok some_value - Đại diện cho kết quả được trả về

  • Err - Đại diện cho thông báo lỗi sẽ được trả lại nếu các điều kiện mong đợi không được thỏa mãn.

Minh họa 1

Hãy thử ví dụ sau trong 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

Hàm String.toInt trả về giá trị Integer nếu tham số được truyền vào là hợp lệ. Nếu tham số không phải là số, hàm sẽ trả về lỗi.

Minh họa 2

Ví dụ sau chấp nhận tuổi làm tham số. Hàm trả về tuổi nếu nó nằm trong khoảng từ 0 đến 135, nếu không nó sẽ trả về một thông báo lỗi thích hợp.

Step 1 - Tạo tệp ResultDemo.elm và thêm đoạn mã sau vào đó.

--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 - Nhập mô-đun trong gói elm và thực thi như dưới đây

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

Trong chương này, chúng ta sẽ thảo luận về cách chuẩn để tạo ứng dụng trong nền tảng Elm. Elm sử dụng một mẫu kiến ​​trúc tương tự như mẫu Model-View-Controller.

Sau đây là bốn phần chính của Kiến trúc Elm.

  • Model
  • View
  • Message
  • Update

Kiến trúc Elm hoạt động như thế nào

Các modelchứa trạng thái ứng dụng. Ví dụ: nếu một ứng dụng hiển thị danh sách khách hàng thì trạng thái sẽ chứa từng dữ liệu khách hàng. Để hiển thị trạng thái một cách dễ hiểu,view/ html phải được tạo. Khi người dùng tương tác với chế độ xem bằng cách nhấn nút hoặc nhập dữ liệu vào biểu mẫu, chế độ xem sẽ tạo ra các tín hiệu được gọi làmessages. Tin nhắn được chuyển đếnupdatephương pháp này đánh giá thông điệp và thực hiện hành động thích hợp. Do đó, phương pháp cập nhật sẽ tạo ra một mô hình mới.

Mô hình mới tạo ra một chế độ xem mới. Chế độ xem sẽ dẫn đến các tương tác mới từ người dùng để gửi tín hiệu thông báo, chuyển sang chức năng cập nhật. Hơn nữa, chức năng tạo ra một mô hình mới. Vì vậy, chu kỳ lặp lại như thể hiện trong sơ đồ trên.

Mô hình

Mô hình xử lý trạng thái của ứng dụng. Cú pháp để xác định Mô hình được đưa ra dưới đây:

-- Model syntax

type alias Model = {
   property1:datatype,
   proptery2:datatype
...
}

Để tạo một mô hình, trước tiên chúng ta cần tạo một mẫu với tất cả các thuộc tính cần thiết trong đó. Mỗi thuộc tính chỉ định trạng thái của ứng dụng.

Lượt xem

View là một đại diện trực quan của trạng thái ứng dụng. Chế độ xem biết cách lấy dữ liệu và tạo trang web từ đó. Khi người dùng tương tác với Chế độ xem, người dùng có thể thao tác trạng thái bằng cách tạo thông báo. Cú pháp để xác định Chế độ xem được đưa ra dưới đây:

--View Syntax
view model =some_implementation

Thông điệp

Thông báo là một yêu cầu từ người dùng để thay đổi trạng thái ứng dụng. Thông báo được chuyển dưới dạng tham số cho chức năng cập nhật.

--Message Syntax
type Message = Message1 |Message2 ...

Cú pháp hiển thị một loại Tin nhắn. Ứng dụng cây du sẽ chỉnh sửa trạng thái dựa trên các thông báo được chuyển đến nó. Các quyết định này được thực hiện trong phương pháp cập nhật.

Cập nhật

Hàm cập nhật diễn giải các thông báo, được truyền dưới dạng tham số cho nó và cập nhật mô hình.

--Update Syntax
update Message_type model =
   some_implementation

Chức năng cập nhật mất Message và Mô hình dưới dạng tham số.

Trình quản lý gói là một công cụ dòng lệnh tự động hóa quá trình cài đặt, nâng cấp, cấu hình và gỡ bỏ các gói trong ứng dụng của bạn.

Giống như JavaScript có trình quản lý gói được gọi là npm, cây du có trình quản lý gói được gọi là elm-package .

Trình quản lý gói thực hiện ba tác vụ sau:

  • Cài đặt tất cả các phụ thuộc mà ứng dụng cây du cần
  • Xuất bản các gói tùy chỉnh
  • Xác định phiên bản gói của bạn khi bạn sẵn sàng xuất bản và cập nhật.

Lệnh Elm Package Manager

Bảng sau liệt kê các lệnh quản lý gói Elm khác nhau:

Sơ không. Chỉ huy Cú pháp Sự miêu tả
1 Tải về cài đặt gói elm Cài đặt các gói để sử dụng cục bộ
2 công bố xuất bản gói cây du Xuất bản gói của bạn vào danh mục trung tâm
3 băng gói cây du Số phiên bản lỗi dựa trên các thay đổi API
4 khác biệt Elm-gói khác nhau Nhận được sự khác biệt giữa hai API

Để xuất bản gói của mình, bạn cần lưu trữ mã nguồn trên GitHub và có phiên bản được gắn nhãn git đúng cách. Hình minh họa sau đây cho thấy cách sử dụng trình quản lý gói elm để kéo một phụ thuộc bên ngoài.

Hình minh họa - Cài đặt gói svg

Trong ví dụ này, chúng ta sẽ thấy cách tích hợp Đồ họa Vectơ có thể mở rộng (SVG) vào một ứng dụng cây du.

Step 1 - Tạo một thư mục elmSvgApp

Step 2 - Cài đặt gói svg bằng lệnh sau -

elm-package install elm-lang/svg

Step 3- Cài đặt Tạo tệp SvgDemo.elm và nhập nội dung được đưa ra bên dưới. Chúng tôi nhập mô-đun Svg để vẽ một hình chữ nhật có kích thước 100x100 và tô màu đỏ.

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- Bây giờ xây dựng dự án bằng cách sử dụng elm make. \ SvgDemo.elm. Điều này sẽ tạo ra một index.html như được hiển thị bên dưới -

Thông báo là một thành phần trong kiến ​​trúc Elm. Các thành phần này do Chế độ xem tạo ra để đáp ứng tương tác của người dùng với giao diện của ứng dụng. Tin nhắn đại diện cho yêu cầu của người dùng để thay đổi trạng thái của ứng dụng.

Cú pháp

--Message Syntax
type Message = some_message1 |some_message2 ...|some_messageN

dục vọng

Ví dụ sau đây là một ứng dụng truy cập đơn giản. Ứng dụng tăng và giảm giá trị của một biến số 1 khi người dùng nhấp vào các nút Thêm và Trừ tương ứng.

Ứng dụng sẽ có 4 thành phần. Các thành phần được mô tả bên dưới:

Thông điệp

Thông báo cho ví dụ này sẽ là -

type Message = Add | Subtract

Mô hình

Mô hình đại diện cho trạng thái của ứng dụng. Trong ứng dụng bộ đếm, định nghĩa mô hình được đưa ra dưới đây; trạng thái ban đầu của bộ đếm sẽ bằng không.

model = 0

Lượt xem

Chế độ xem đại diện cho các yếu tố trực quan của ứng dụng. Dạng xem có hai nút (+) và (-). Thông báo Thêm và Trừ được Chế độ xem tạo ra khi người dùng nhấp vào nút + và - tương ứng. Giá trị đã sửa đổi của mô hình sau đó được hiển thị bởi Chế độ xem.

view model =
-- invoke text function
h1[]
[   div[] [text "CounterApp from TutorialsPoint" ]
   ,button[onClick Subtract] [text "-"]
   ,div[][text (toString model)]
   ,button[onClick Add] [text "+"]
]

Update

This component contains code that should be executed for each message generated by the view. This is shown in the example below −

update msg model =
case msg of
Add -> model+1
Subtract -> model-1

Putting it all together

Step 1 − Create a folder MessagesApp and file MessagesDemo.elm

Step 2 − Add the following code in elm file −

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 − Execute the elm make command in terminal. The elm make command compiles the code and generates an HTML file from the .elm file created above.

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 − Open the index.html and verify the working as shown below −

Elm - Commands

In the previous chapters, we discussed the various components of Elm architecture and their functions. The user and the application communicate with one another using Messages.

Consider an example, where the application needs to communicate with other components like an external server, APIs, microservice, etc. to serve the user request. This can be achieved by using Commands in Elm. Messages and commands are not synonymous. Messages represent the communication between an end user and the application while commands represent how an Elm application communicates with other entities. A command is triggered in response to a message.

The following figure shows the workflow of a complex Elm application −

The user interacts with the view. The view generates an appropriate message based on the user's action. The update component receives this message and triggers a command.

Syntax

The syntax for defining a command is as given below −

type Cmd msg

The message generated by the view is passed to the command.

Illustration

The following example makes a request to an API and displays the result from the API.

The application accepts a number from the user, passes it to the Numbers API. This API returns facts related to the number.

The various components of the application are as follows −

Http Module

The Http Module of Elm is used to create and send HTTP requests. This module is not a part of the core module. We will use the elm package manager to install this package.

API

In this example, the application will communicate with the Numbers API – "http://numbersapi.com/#42".

View

The application's view contains a textbox and a button.

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]
      ]

Model

The Model represents the value entered by the user and the result that will be returned by the API.

type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

Message

The application has the following three messages −

  • ShowFacts
  • Input
  • NewFactArrived

Upon clicking the Show Facts button, ShowFacts message is passed to the update method. When the user types some value in the textbox, the Input message is passed to update method. Finally, when the Http server response is received, the NewFactArrived message will be passed to update.

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

Update

The update method returns a tuple, which contains the model and command objects. When the user clicks on the Show Facts button, the Message is passed to the update which then calls the 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)

Helper Function

The helper function getRandomNumberFromAPI invokes the NumbersAPI and passes to it the number entered by the user. The result returned by the API is used to update the model.

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
         "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)
Sr. No. Method Signature Description
1 Http.getString getString : String -> Request String Create a GET request and interpret the response body as a String.
2 Http.send send:(Result Error a -> msg) -> Request a -> Cmd msg Send a Http request.

main

This is the entry point of the Elm project.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Putting it all together

Step 1 − Create folder CommandApp and file CommandDemo.elm.

Step 2 − Install http module using command elm package install elm-lang/http.

Step 2 − Type the contents for CommandDemo.elm as shown below −

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 − Fire the command.

C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm

This will generate the html file as shown below.

Elm - Subscriptions

In the previous chapter, we discussed that a View interacts with other components using Commands. Similarly, a component (E.g. WebSocket) can talk to a View using Subscriptions. Subscriptions are a way that an Elm application can receive external inputs like keyboard events, timer events and WebSocket events.

The following figure explains the role of Subscriptions in an Elm application. The user interacts with an Elm application via messages. The application given uses WebSocket and it has two modes of operations −

  • Send client-side data to socket server via Command
  • Receive data anytime from the socket server via Subscription

Syntax

The syntax for defining a subscription is given below −

type Sub msg

Illustration

Let us understand subscriptions using a simple example.

In the example given below, the application sends a message to the server. The server is an echo server, which responds to the client with the same message. All the incoming messages are later displayed in a list. We will use WebSocket (wss protocol) to be able to continuously listen for messages from the server. The WebSocket will send user input to the server using Commands while it will use Subscription to receive messages from the server.

The various components of the application are given below −

Echo server

The echo server can be accessed using the wss protocol. The echo server sends back user input to the application. The code for defining an echo server is given below −

echoServer : String
echoServer =
"wss://echo.websocket.org"

Model

The Model represents user input and a list of incoming messages from the socket server. The code for defining the Model is as given below −

type alias Model =
   { input : String
   , messages : List String
   }

Messages

The message type will contain Input for taking text input from user. The Send message will be generated when user clicks the button to send message to WebSocket server. The NewMessage is used when message arrives from echo server.

type Msg
   = Input String
   | Send
   | NewMessage String

View

The application's view contains a textbox and a submit button to send user input to the server. The response from the server is displayed on the View using a div tag.

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 ]

Update

The update function takes the message and the model components. It updates the model based on the message type.

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. Method Signature Description
1 WebSocket.listen listen : String -> (String -> msg) -> Sub msg Subscribes to any incoming messages on a websocket.
2 WebSocket.send send : String -> String -> Cmd msg Sends a wss request to a server address. It is important that you are also subscribed to this address with listen. If you are not, the web socket will be created to send one message and then closed.

Subscription

The subscription function takes in the model object. To receive the messages from WebSocket server, we call WebSocket.listen passing in the message as NewMessage. When a new message comes from the server, the update method is called.

subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen echoServer NewMessage

main

The main function is the entry point to the elm application as shown below.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Putting it all together

Step 1 − Create a directory,SubscriptionApp and add a file,SubscriptionDemo.elm to it.

Step 2 − Add the following contents to SubscriptionDemo.elm file −

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 − Install the websockets package using elm package manager.

C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket

Step 4 − Build and generate index.html file as shown below.

C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm

Step 5 − Upon execution, the following output will be generated −