Elm-quick-guide

提供:Dev Guides
移動先:案内検索

ニレ-はじめに

Elmは関数型プログラミング言語です。 2012年にEvan Czaplickiによって設計されました。

Elmは、Webアプリケーションのフロントエンドの設計に特に使用されます。

ElmはJavaScriptにコンパイルされ、ブラウザーで実行されます。 それは高速で、テスト可能で、保守可能であり、ランタイム例外はありません。

Elmプログラミングプラットフォームの実用的なアプリケーションには次のものがあります-

  • ゲーム
  • グラフィックス
  • シングルページアプリケーション

なぜエルム

Elmは、フロントエンド開発者が直面する一般的な問題のほとんどを取り除きます。 これには以下が含まれます-

ランタイム例外なし

Elmは静的に型付けされた言語です。 考えられるすべてのエラーは、コンパイル時に検証および修正されます。 これにより、実行時例外をなくすことができます。

開発者向けのエラーメッセージ

他のプログラミング言語とは異なり、Elmのコンパイラは、コンパイル時に非常に具体的で開発者に優しいエラーメッセージを提供するように設計されています。 エラーメッセージには、推奨設計ドキュメントへのリンクなどのヒントも含まれています。

テストが簡単

各Elm機能は、他のすべての機能とは別にテストできます。 これにより、Elmで書かれたプログラムを簡単にテストできます。

自動セマンティックバージョニング

Elmは、パッケージの自動セマンティックバージョン管理を実施します。 これにより、パッチの変更がすでに実行中のアプリケーションをクラッシュさせないことが保証されます。

再利用可能なコード

Elm関数は、JavaScript、Python、またはTypeScriptの関数と比較して、本質的に再利用が簡単です。

エルム-環境設定

この章では、Windows、Mac、およびLinuxプラットフォームにElmをインストールする手順について説明します。

ローカル環境のセットアップ

ローカル環境にElmをインストールするには、以下に示す手順を検討してください。

ステップ1-ノードのインストール

elmはJavaScriptにコンパイルされるため、ターゲットマシンには node がインストールされている必要があります。 nodenpm をセットアップする手順については、finddevguides NodeJSコースを参照してください。

Node setup。

  • ステップ2-elm *をインストールする

端末で次のコマンドを実行して、elmをインストールします。 このコースを書いている時点では、elmの安定バージョンは0.18でした。

npm install -g [email protected]

Install elm

インストール後、次のコマンドを実行してElmのバージョンを確認します。

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

ステップ2-エディターのインストール

ここで使用する開発環境はVisual Studio Code(Windowsプラットフォーム)です。

Visual Studio Codeは、Visual StudioのオープンソースIDEです。 Mac OS X、Linux、およびWindowsプラットフォームで使用できます。 VSCodeは

https://code.visualstudio.com/。

Windowsへのインストール

このセクションでは、WindowsにElmをインストールする手順について説明します。

Windows用のhttps://code.visualstudio.com/[[[1]]]をダウンロードします。

VSCodeSetup.exeをダブルクリックして、セットアッププロセスを開始します。 これには数分しかかかりません。

VSCodeSetup

[ファイル]→[コマンドプロンプトで開く]を右クリックして、ファイルのパスに直接移動できます。 同様に、[エクスプローラで表示]オプションは、ファイルエクスプローラにファイルを表示します。

エクスプローラーの公開

Mac OS Xでのインストール

Visual Studio CodeのMac OS X固有のインストールガイドは、https://code.visualstudio.com/docs/setup/setup-overview [VSCode Installation-MAC]にあります。

Linuxへのインストール

Visual Studio CodeのLinux固有のインストールガイドは、https://code.visualstudio.com/docs/setup/setup-overview [VSCode Installation-Linux]にあります。

ステップ4-elm拡張機能のインストール

以下に示すように、VSCodeにelm拡張機能をインストールします。

Linuxのインストール

エルムREPL

REPLはRead Eval Print Loopの略です。 これは、コマンドが入力され、システムが対話モードで出力を返すWindowsコンソールやUnix/Linuxシェルなどのコンピューター環境を表します。

ElmはREPL環境にバンドルされています。 次のタスクを実行します-

  • 読み取り-ユーザーの入力を読み取り、入力をelmデータ構造に解析し、メモリに保存します。
  • Eval-データ構造を取り、評価します。
  • Print-結果を印刷します。
  • Loop-ユーザーが終了するまで上記のコマンドをループします。 コマンド:exitを使用してREPLを終了し、ターミナルに戻ります。

REPLに2つの数字を追加する簡単な例を以下に示します-

VSCodeターミナルを開き、コマンドelm REPLを入力します。

REPLターミナルは、ユーザーが何らかの入力を入力するのを待ちます。 次の式10 + 20を入力します。 REPL環境は、以下のように入力を処理します-

  • ユーザーから数値10および20を読み取ります。
  • +演算子を使用して評価します。
  • 結果を30として出力します。
  • 次のユーザー入力のためにループします。 ここでループを終了します。

Elm REPL

Elm-基本構文

この章では、elmで簡単なプログラムを作成する方法について説明します。

ステップ1-VSCodeにディレクトリHelloAppを作成します

ここで、このディレクトリに Hello.elm というファイルを作成します。

ディレクトリの作成

上の図は、プロジェクトフォルダー HelloApp とVSCodeで開いたターミナルを示しています。

ステップ2-必要なelmパッケージをインストールします

elmのパッケージマネージャーは_elm-package_です。 _elm-lang/html_パッケージをインストールします。 このパッケージは、ブラウザにelmコードの出力を表示するのに役立ちます。

VSCodeのコマンドプロンプトで[ファイル]→[開く]を右クリックして、 HelloApp プロジェクトフォルダーに移動します。

ターミナルウィンドウで次のコマンドを実行します-

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

パッケージをインストールすると、次のファイル/フォルダーがプロジェクトディレクトリに追加されます。

  • elm-package.json(ファイル)、プロジェクトのメタデータを保存します
  • elm-stuff(フォルダ)、外部パッケージを保存します

パッケージが正常にインストールされると、次のメッセージが表示されます。

インストール済みパッケージ

ステップ3-次のコードをHello.elmファイルに追加します

-- importing Html module and the function text
import Html exposing (text)

-- create main method
main =
-- invoke text function
text "Hello Elm from finddevguides"

上記のプログラムは、ブラウザに「 Hello Elm from finddevguides 」という文字列メッセージを表示します。

このため、関数 textHtml モジュール内にインポートする必要があります。 テキスト関数は、ブラウザで文字列値を印刷するために使用されます。 主な方法は、プログラムへのエントリポイントです。 _main_メソッドは_text_関数を呼び出し、文字列値を渡します。

ステップ4-プロジェクトをコンパイルします

VSCodeターミナルウィンドウで次のコマンドを実行します。

elm make Hello.elm

上記のコマンドの出力は以下のとおりです-

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

上記のコマンドは indexl ファイルを生成します。 elmコンパイラーは.elmファイルをJavaScriptに変換し、 indexl ファイルに埋め込みます。

ステップ5-ブラウザでindexlを開きます

任意のブラウザーで_indexl_ファイルを開きます。 出力は以下のようになります-

ブラウザを開く

Elmのコメント

コメントは、プログラムの可読性を向上させる方法です。 コメントを使用して、コードの作成者などのプログラムに関する追加情報、関数構成体に関するヒントなどを含めることができます。 コメントはコンパイラによって無視されます。

エルムはコメントの次のタイプをサポートしています-

  • 単一行のコメント(-)−-と行末までのテキストはコメントとして扱われます。
  • 複数行コメント(\ {--})-これらのコメントは複数行にわたる場合があります。

-- this is single line comment

{- This is a
   Multi-line comment
-}

行とインデント

Elmは、関数定義またはフロー制御のコードブロックを示す中括弧を提供しません。 コードのブロックは、行のインデントによって示され、厳密に強制されます。 ブロック内のすべてのステートメントは、同じ量だけインデントする必要があります。 たとえば-

module ModuleIf exposing (..)
x = 0

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

ただし、次のブロックはエラーを生成します-

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

したがって、エルムでは、同じ数のスペースでインデントされたすべての連続行がブロックを形成します。

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

ニレ-データ型

型システムは、言語でサポートされているさまざまなタイプの値を表します。 タイプシステムは、プログラムによって保存または操作される前に、指定された値の有効性をチェックします。 これにより、コードが期待どおりに動作することが保証されます。 タイプシステムはさらに、より豊富なコードヒントと自動化されたドキュメントも可能にします。

Elmは静的に型付けされた言語です。 Elmのタイプは、他の言語のタイプと似ています。

_number_データ型は数値を表します。 エルム型システムは、次の数値型をサポートしています-

Sr. No. Type Example
1 number − Stores any number 7 is number type
2 Float − Stores fractional values 7/2 gives 3.5 result as Float
3 Int − Stores non-fractional values 7//2 gives 3 result as Int

タイプ_number_は、小数値と非小数値の両方に対応します。 elm REPLを開き、以下に示す例を試してください-

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_データ型は、一連の文字を表すために使用されます。 _Char_データ型は、単一の文字を表すために使用されます。 _String_値は二重引用符で囲まれて定義され、_Char_値は単一引用符で囲まれます '。

Sr. No. Type Example
1 String − Stores a sequence of characters "finddevguides"
2 Char − Stores fractional values 'T'

elm REPLを開き、以下に示す例を試してください-

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>
--------------------------------------
------------------------------------------
> "finddevguides"
"finddevguides" : String
> 'T'
'T' : Char

Bool

ElmのBoolデータ型は、TrueとFalseの2つの値のみをサポートします。 キーワードBoolは、ブール値を表すために使用されます。

Sr. No. Type Example
1 Bool − Stores values True or False 1==1 returns True

elm REPLを開き、以下に示す例を試してください-

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

カスタムタイプ

Elmはユーザー定義型の作成をサポートしています。 たとえば、支払いアプリケーションを考えます。 アプリケーションでは、クレジットカード、デビットカード、ネットバンキングなど、さまざまな支払い方法を保存する必要があります。 これは、カスタムタイプを定義し、その値を3つの許容可能な支払いモードに制限することで実現できます。

次の例は、カスタムタイプを作成する方法を示しています。

> 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

上記の例では、PaymentModeカスタムタイプを作成しました。 変数payment1およびpayment2は、PaymentMode値に割り当てられます。 変数に割り当てられた値がPaymentModeタイプで定義された値のいずれとも一致しない場合、アプリケーションは構文エラーをスローします。

構造化データ型

構造化データ型を使用して、複数の値を構造化形式で保存できます。 エルムは、次の構造化データ型をサポートしています-

  • タプル
  • List
  • 記録
  • 記録

これらについては、今後の章で詳しく説明します。

エルム-変数

定義により、変数は値を格納する「メモリ内の名前付きスペース」です。 つまり、プログラムの値のコンテナとして機能します。 変数は、プログラムが値を保存および操作するのに役立ちます。

Elmの変数は、特定のデータ型に関連付けられています。 データ型は、変数のメモリのサイズとレイアウト、そのメモリ内に格納できる値の範囲、および変数に対して実行できる一連の操作を決定します。

変数の命名規則

このセクションでは、変数の命名規則について学びます。

  • 変数名は、文字、数字、アンダースコア文字で構成できます。
  • 変数名は数字で始めることはできません。 文字またはアンダースコアで始まる必要があります。
  • Elmでは大文字と小文字が区別されるため、大文字と小文字は区別されます。

Elmの変数宣言

Elmで変数を宣言するための型構文は以下のとおりです-

構文1

variable_name:data_type = value

「:」構文(型注釈と呼ばれる)は、変数をデータ型に関連付けるために使用されます。

構文2

variable_name = value-- no type specified

Elmで変数を宣言する際のデータ型はオプションです。 この場合、変数のデータ型は、それに割り当てられた値から推測されます。

この例では、VSCodeエディターを使用してelmプログラムを作成し、elm replを使用して実行します。

ステップ1-プロジェクトフォルダーの作成-VariablesApp。 プロジェクトフォルダーにVariables.elmファイルを作成します。

次のコンテンツをファイルに追加します。

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

プログラムはモジュール変数を定義します。 モジュールの名前は、elmプログラムファイルの名前と同じでなければなりません。 (..)構文は、モジュール内のすべてのコンポーネントを公開するために使用されます。

プログラムは、_String_型の可変メッセージを宣言します。

イラスト

ステップ2-プログラムを実行します。

  • VSCodeターミナルで次のコマンドを入力して、elm REPLを開きます。
elm repl
  • REPLターミナルで次のelmステートメントを実行します。
> 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
>

Elm REPLを使用して、次の例を試してください。

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 = "finddevguides"
"finddevguides" : String
> location = "Hyderabad"
"Hyderabad" : String
> rating = 4.5
4.5 : Float

ここで、変数companyおよびlocationは文字列変数であり、評価はフロート変数です。

elm REPLは、変数の型注釈をサポートしていません。 次の例は、変数の宣言中にデータ型が含まれている場合にエラーをスローします。

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.

elm REPLの使用中に改行を挿入するには、以下に示すように\構文を使用します-

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
| = "finddevguides" -- secondLine
"finddevguides" : String

エルム-演算子

演算子は、データに対して実行される機能を定義します。 演算子が機能する値は、オペランドと呼ばれます。 次の式を考えてください

7 + 5 = 12

ここで、値7、5、および12はオペランドであり、+および=は演算子です。

エルムの主要な演算子は次のように分類できます-

  • 算術
  • リレーショナル
  • 論理的

算術演算子

変数aおよびbの値がそれぞれ7および2であると仮定します。

link:/elm/elm_arithmatic_operators [例を表示]

Sr. No. Operator Description Example
1 +(Addition) returns the sum of the operands a+b is 9
2 -(Subtraction) returns the difference of the values a-b is 5
3 * (Multiplication) returns the product of the values a*b is 14
4 /(Float Division) performs division operation and returns a float quotient a/b is 3.5
5 //(Integer Division) performs division operation and returns a integer quotient a//b is 3
6 % (Modulus) performs division operation and returns the remainder a % b is 1

関係演算子

関係演算子は、2つのエンティティ間の関係の種類をテストまたは定義します。 これらの演算子は、2つ以上の値を比較するために使用されます。 関係演算子はブール値を返します。 正しいか間違っているか。

_a_の値が10で、_b_が20であると仮定します。

link:/elm/elm_relational_operators [例を表示]

Sr. No. Operator Description Example
1 > Greater than (a > b) is False
2 < Lesser than (a < b) is True
3 >= Greater than or equal to (a >= b) is False
4 Lesser than or equal to (a ⇐ b) is True
5 == Equality (a == b) is false
6 != Not equal (a != b) is True

比較可能なタイプ

=や<などの比較演算子は、比較可能な型で機能します。 これらは、数字、文字、文字列、リスト、タプルとして定義されます。 演算子の両側の比較可能な型は同じでなければなりません。

Sr. No. Comparable Type Example
1 number 7>2 gives True
2 character 'a' =='b' gives False
3 string "hello" =="hello" gives True
4 tuple (1,"One")==(1,"One") gives True
5 list [1,2]==[1,2] gives True

elm REPLを開き、以下に示す例を試してください-

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
>

論理演算子

論理演算子は、2つ以上の条件を結合するために使用されます。 論理演算子もブール値を返します。

link:/elm/elm_logical_operators [例を表示]

Sr. No. Operator Description Example
1 && The operator returns true only if all the expressions specified return true (10>5) && (20>5) returns True
2
The operator returns true if at least one of the expressions specified return true (10 < 5) (20 >5) returns True
3 not The operator returns the inverse of the expression’s result. For E.g.: !(>5) returns false. not (10 < 5) returns True
4 xor The operator returns true only if exactly one input returns true. The operator returns false if both the expressions return true. xor (10 > 5 ) (20 > 5) returns false

ニレ-意思決定

意思決定構造では、プログラマーが、プログラムによって評価またはテストされる1つ以上の条件、および条件が真であると判断された場合に実行されるステートメント、およびオプションで、条件は偽と判断されます。

以下に、ほとんどのプログラミング言語で見られる典型的な意思決定構造の一般的な形式を示します

意思決定

意思決定構造は、命令が実行される前に条件を評価します。 エルムの意思決定構造は次のように分類されます-

Sr. No. Statement Description
1 if…​then…​else statement The if statement consists of a Boolean expression followed by then which is executed if the expression returns true and else which is executed if the expression returns false
2 nested if statement You can use one if…​then…​else inside another if.
3 case statement Tests the value of a variable against a list of values.

if …​ then …​ elseステートメント

*if…then* コンストラクトは、コードブロックが実行される前に条件を評価します。 ブール式の評価がtrueの場合、thenステートメント内のコードブロックが実行されます。 ブール式の評価がfalseの場合、elseステートメント内のコードブロックが実行されます。

他のプログラミング言語とは異なり、Elmではelseブランチを提供する必要があります。 そうでない場合、Elmはエラーをスローします。

構文

if boolean_expression then statement1_ifTrue else statement2_ifFalse

REPLターミナルで次の例を試してください。

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

ネストされた場合

ネストされたifステートメントは、複数の条件をテストするのに役立ちます。 ネストされたifステートメントの構文は以下のとおりです-

if boolean_expression1 then statement1_ifTrue else if boolean_expression2 then statement2_ifTrue else statement3_ifFalse

Elm REPLで次の例を試してください-

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

ケースステートメント

case文は、if then else文を簡素化するために使用できます。 ケース文の構文は以下のとおりです-

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

caseステートメントは、変数の値が定義済みの定数セットと一致するかどうかを確認し、対応する値を返します。 各ケースで返される値は同じタイプでなければならないことに注意してください。 変数値が指定された定数のいずれとも一致しない場合、コントロールは default (//_で示される)に渡され、対応する値が返されます。

Elm REPLで次の例を試してください-

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

上記のコードスニペットは、nの値がゼロかどうかを確認します。 コントロールはデフォルトに渡され、「n is not Zero」という文字列が返されます。

エルム-ループ

Elmは関数型プログラミング言語です。 Elmは、従来のループ構造の代わりに再帰の概念を使用します。

この章では、再帰の概念について説明します。

再帰

一部のコンピュータープログラミング言語では、モジュールまたは関数が自分自身を呼び出すことができます。 この手法は、再帰として知られています。

このプログラムでは、再帰を使用してhelloを5回表示する方法を説明します。

  • ステップ1-ファイルLoop.elm *を作成します

モジュールループを作成し、関数 sayHello を定義します。 関数sayHelloは整数値を入力として受け取り、文字列値を返します。

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

関数sayHelloは、渡されたパラメーターが1かどうかを確認します。 パラメータが1の場合、関数は戻ります。それ以外の場合、文字列Helloを作成して同じ関数を呼び出します。

ステップ2-REPLからsayHelloを呼び出す

現在のプロジェクトフォルダ(Loop.elmファイルの場所)からelm REPLを開きます。

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

モジュールループ

次の例では、再帰を使用してn個の数値の合計を出力します。

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

elm REPLでは、入力番号を取得し、0からその番号までのすべての数値を合計する関数sumOfNosを作成しました。

たとえば、入力を5として渡すと、1 + 2 + 3 + 4 + 515)が合計されます。

> ssumOfNos 5
15 : number

プログラムの出力は上に示されています。

エルム-関数

関数はElmプログラムの構成要素です。 関数は、特定のタスクを実行するための一連のステートメントです。

関数は、プログラムをコードの論理ブロックに編成します。 定義すると、コードにアクセスするために関数を呼び出すことができます。 これにより、コードが再利用可能になります。 さらに、関数を使用すると、プログラムのコードの読み取りと保守が簡単になります。

関数を使用する手順

関数を使用するには3つのステップがあります-

関数宣言

関数宣言は、関数の名前、戻り値の型、およびパラメーターについてコンパイラーに通知します。 関数を宣言するための構文は以下のとおりです-

fn_name:data_type_of_the_parameters ->return_type

関数宣言は以下を指定します-

  • 関数の名前。
  • パラメーターのデータ型。 関数にはパラメーターがある場合とない場合があるため、これはオプションです。
  • 関数が返す値のデータ型。 Elmは関数型プログラミング言語であるため、Elmの関数は常に値を返す必要があります。 他のプログラミング言語の関数とは異なり、Elm関数は値を返すためにreturnキーワードを使用しません。

関数定義または関数実装

関数定義は、関数の実際の本体を提供します。 関数定義は、特定のタスクの実行方法を指定します。 関数を定義するための構文は以下のとおりです-

fn_name parameter1 parameter2 = statements

関数の呼び出しまたは呼び出し

関数を実行するには、関数を呼び出す必要があります。 関数を呼び出すための構文は以下のとおりです-

fn_name parameter1 parameter2

次のコードは、関数greetを定義しています。 この関数は、文字列「Hello」を返します。

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

パラメータ化された関数

パラメータは、関数に値を渡すためのメカニズムです。 パラメーターの値は、関数の呼び出し時に関数に渡されます。

イラスト1

次の例では、_fn_add_関数を定義しています。 この関数は、パラメーターとして2つの数値を受け入れ、それらの合計を返します。 elm REPLで次を試してください-

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

イラスト2

次の例では、sayHello関数を定義しています。 sayHello関数は、パラメーターとして文字列値を受け入れて返し、文字列を返します。

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

パイプオペレーター

パイプ演算子|>を理解するために、さまざまな文字列_ ["a"、 "b"、 "c"] _のリストがある例を考えてみましょう。 今、我々はで区切られている単一の文字列が必要です-

次の例は、_String.join_を使用してこれを行う方法を示しています

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

パイプ演算子|>を使用して、同じアクションを実行できます。 パイプ演算子を使用して、複数の関数呼び出しを連鎖できます。

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

最初の例では、リストを連結してメソッドを結合しています。 2番目のケースでは、同じリストが逆関数にパイプされ、その後、結合されて結合されます。 そのため、リストは反転して結合されて表示されます。

ニレ-ひも

Unicode文字のシーケンスは、ストリングと呼ばれます。 Elmでは、文字列は "" _double quotes_で囲まれています。 以下に示すように、文字列はテキストの塊です。

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

文字列関数

文字列値のクエリまたは操作に使用できる一般的な関数を以下に示します。 REPLを使用して、以下に示す例を試してください。

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

この関数は、文字列が空かどうかを判断するために使用できます。 指定された文字列が空の場合、この関数はTrueを返します。

構文

String.isEmpty String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

関数のシグネチャは、戻り値の型としてブールを示し、文字列としての入力型を示しています-

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

この関数は文字列を反転します。

構文

String.reverse String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

関数のシグネチャは、戻り値の型として文字列を示し、文字列として入力型を示します-

> String.reverse "finddevguides"
"tnioPslairotuT" : String

長さ

この関数は、文字列の長さを返します。

構文

String.length String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

関数のシグネチャは、戻り値の型としてIntを、文字列としての入力型を示します。

> String.length "Mohtashim"
9 : Int

追加する

この関数は、2つの文字列を追加して新しい文字列を返します。

構文

String.append String_value1 String_value2

関数の署名を確認するには、elm REPLに次のように入力します-

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

2つのストリング入力パラメーターと1つのストリング出力パラメーターのショーの署名

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

コンカット

この関数は、多くの文字列を1つに連結して新しい文字列を返します。

構文

String.concat [String1,String2,String3]

関数の署名を確認するには、elm REPLに次のように入力します-

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

の署名は、文字列の入力パラメータと文字列の戻り値の型のリストを示しています

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

スプリット

この関数は、指定されたセパレータを使用して文字列を分割します。

構文

String.split string_seperator String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

の署名は、2つの入力文字列パラメーターと、文字列型のリストとしての出力を示しています。

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

スライス

この関数は、開始インデックスと終了インデックスが指定された部分文字列を返します。 負のインデックスはリストの最後から取得されます。 インデックスの値はゼロから始まります。

構文

String.slice start_index end_index String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

の署名は、3つの入力パラメーターと1つの戻り値の型を示しています。

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

含む

2番目の文字列に最初の文字列が含まれている場合、この関数はTrueを返します。

構文

String.contains string1 string2

関数の署名を確認するには、elm REPLに次のように入力します-

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

bool戻り値の型と2つの入力パラメーターを示す署名

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

toInt

この関数は、文字列をintに変換します。

構文

String.toInt string_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

toIntはエラーを返す可能性があるため、戻り値のタイプはResult、つまりStringまたはIntです。

> 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

この関数は、文字列をfloatに変換します。

構文

String.toFloat string_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

toFloatはエラーを返す可能性があるため、戻り値のタイプはResultで、StringまたはFloatです。

> 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

この関数は、指定された文字から文字列を作成します。

構文

String.fromChar character_value

elm REPLで次の関数型の署名を確認するには-

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

シグネチャは、戻り値の型として文字列を示し、Char型として入力を示します

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

toList

この関数は、文字列を文字のリストに変換します。

構文

String.toList string_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

署名は、関数が文字のリストを返し、文字列を入力することを示しています。

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

fromList

この関数は、文字のリストを文字列に変換します。

構文

String.fromList list_of_characters

関数の署名を確認するには、elm REPLに次のように入力します-

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

署名は、関数が文字のリストを返し、文字列を入力することを示しています。

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

toUpper

この関数は、文字列をすべて大文字に変換します。

構文

String.toUpper String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

toLower

この関数は、文字列をすべて小文字に変換します。

構文

String.toLower String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

trim

この関数は、文字列の両側の空白を取り除きます。

構文

String.trim String_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

> String.trim "finddevguides "
"finddevguides" : String

フィルタ

この関数は、入力文字列から文字セットをフィルタリングします。 テストに合格した文字のみを保持します。

構文

String.filter test_function string_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

シグニチャーは、フィルターが2つの入力パラメーターを取り、ストリングを返すことを示しています。 最初のパラメーターは、入力Charを持ち、Boolを返す関数です。

この例では、_Char.isUpper_をパラメーターとしてフィルターメソッドに渡します。以下に示すように、すべて大文字を返します。

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

map

この関数は文字列を取り、文字列内のすべての文字を変換します。

構文

String.filter mapping_function string_value

関数の署名を確認するには、elm REPLに次のように入力します-

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

次の例は、文字oを@に置き換えます-

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

ニレ-リスト

List、Tuples、およびRecordデータ構造を使用して、値のコレクションを保存できます。

この章では、Elmでリストを使用する方法について説明します。

リストは同種の値のコレクションです。 リスト内の値はすべて同じデータ型である必要があります。

変数を使用して値を保存する際には、次の制限を考慮してください-

  • 変数は本質的にスカラーです。 つまり、宣言時には、変数は1つの値しか保持できません。 つまり、プログラムにn個の値を格納するには、n個の変数宣言が必要になります。 したがって、値のより大きなコレクションを格納する必要がある場合、変数の使用は実行できません。
  • プログラム内の変数には、ランダムな順序でメモリが割り当てられるため、宣言の順序で値を取得または読み取ることが難しくなります。

構文

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

次の例は、Elmでリストを使用する方法を示しています。 elm REPLでこの例を試してください-

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

異なる型の値をリストに追加しようとすると、コンパイラは型の不一致エラーをスローします。 これを以下に示します。

> 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

リスト操作

次の表は、リストの一般的な操作を示しています-

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

リストが空の場合、この関数はtrueを返します。

構文

List.isEmpty list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

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

この関数はリストを逆にします。

構文

List.reverse list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

長さ

この関数は、リストの長さを返します。

構文

List.length list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

最大

この関数は、空でないリストの最大要素を返します。

構文

List.maximum list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

最小

この関数は、空でないリストの最小要素を返します。

構文

List.minimum list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

sum

この関数は、リスト内のすべての要素の合計を返します。

構文

List.sum list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

製品

この関数は、リスト内のすべての要素の積を返します。

構文

List.product list_name

関数の署名を確認するには、elm REPLに次のように入力します-

<function>  : List number ->  number

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

sort

この関数は、リスト内の最低値から最高値にソートします。

構文

List.sort list_name

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

コンカット

この関数は、リストの束を単一のリストに連結します。

構文

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

関数の署名を確認するには、elm REPLに次のように入力します-

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

> List.concat [[: List number

追加する

この関数は、2つのリストをまとめます。

構文

List.append [list_name1] [list_name2]

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

++演算子を使用して、リストを別のリストに追加することもできます。 これは以下の例に示されています-

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

範囲

この関数は、すべての要素が1ずつ増加する数値のリストを作成します。 リストにあるべき最小値と最大値が関数に渡されます。

構文

List.range start_range end_range

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

フィルタ

この関数は、入力リストから値のセットをフィルタリングします。 テストに合格した値のみを保持します。

構文

List.filter test_function input_list

関数の署名を確認するには、elm REPLに次のように入力します-

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

次の例では、入力リストからすべての偶数をフィルタリングします

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

head

この関数は、入力リストから最初の要素を返します。

構文

List.head input_list

関数の署名を確認するには、elm REPLに次のように入力します-

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

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

tail

この関数は、リストの最初以降のすべての要素を返します。

構文

List.tail input_list

関数の署名を確認するには、elm REPLに次のように入力します-

> List.tail
<function> : List a -> Maybe.Maybe (List 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)

短所演算子の使用

cons演算子(::)は、リストの先頭に要素を追加します。

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

追加する新しい要素とリスト内の値のデータ型は一致する必要があります。 データ型が一致しない場合、コンパイラはエラーをスローします。

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

リストは不変です

リストがElmで不変かどうかを確認しましょう。 最初のリスト_myList_は、値1と連結されたときに新しいリストを作成し、_myListCopy_に返されます。 したがって、初期リストを表示する場合、その値は変更されません。

> 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

ニレ-タプル

時には、さまざまなタイプの値のコレクションを保存する必要があるかもしれません。 Elmは、この目的に役立つtupleと呼ばれるデータ構造を提供します。

タプルは、異種の値のコレクションを表します。 つまり、タプルを使用すると、異なるタイプの複数のフィールドを格納できます。 タプルには、固定数の値が格納されます。 タプルは、関数から異なるタイプの複数の値を返す場合に便利です。 これらのデータ構造は、elmの他の型と同様に不変です。

構文

(data1,data2)

簡単な例を以下に示します-

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

以降のセクションでは、さまざまなタプル操作について学習します。

最初

この操作は、タプルから最初の値を抽出します。

構文

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

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

二番目

*second* タプル操作は、タプルから2番目の値を抽出します。

構文

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

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

タプルのリスト

リストにはタプルを保存できます。 リスト内でタプルを使用する場合は、それらがすべて同じデータ型であり、同じ数のパラメーターを持っていることを確認してください。

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

関数付きのタプル

関数はタプルを返すことができます。 さらに、タプルをパラメーターとして関数に渡すことができます。

イラスト1

次の例では、関数fn_checkEvenを定義しています。 この関数は、整数値をパラメーターとして受け入れ、タプルを返します。

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

イラスト2

以下は、タプルをパラメーターとして関数に渡します。

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

関数_fn_add_は2つの数値を持つタプルを取り、それらの合計を返します。

破壊

構造化には、タプルを個々の値に分割することが含まれます。 3つ以上の要素を持つタプル内の個々の値にアクセスするには、構造化を使用します。 ここでは、タプルの各値を異なる変数に割り当てます。 _を使用すると、無視またはスキップされる値のプレースホルダーを定義できます。

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

この例では、let..inブロック構文を使用して構造を分解します。 letブロックには変数が含まれ、inブロックには評価される式と返される値が含まれます。

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

let節で変数a b cを宣言し、in節を使用してそれらにアクセスしています。

エルム-レコード

Elmのレコードデータ構造を使用して、データをキーと値のペアとして表すことができます。 レコードを使用して関連データを整理し、簡単にアクセスしてデータを更新できるようにします。 ElmレコードはJavaScriptのオブジェクトに似ています。 レコード内のデータ要素はフィールドと呼ばれます。

レコードを定義する

レコードを定義するには、次の構文を使用します-

構文

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

レコードには、複数のタイプのデータを保存できます。 レコード内のフィールド名は、Elm識別子の命名に関する一般的な規則に準拠する必要があります。

レコード値へのアクセス

次の構文を使用して、レコード内の個々のフィールドにアクセスします。

構文

record_name.fieldname

OR

.fieldname record_name

Elm REPLで以下を試してください-

> company = {name="finddevguides",rating=4.5}
{ name = "finddevguides", rating = 4.5 } : { name : String, rating : Float }
> company.name
"finddevguides" : String
> .rating company
4.5 : Float

リストでレコードを使用する

レコードはリスト内に保存できます。 レコードのすべてのフィールド値は同じタイプである必要があります。

構文

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

OR

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

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 }

レコードを更新する

Elmではレコードは不変です。 レコードが更新されると、更新された値を持つ新しいレコードが返されます。 このフィールドは、レコードを更新するときに異なるタイプの値を保持できます。

構文

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

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

次の例は、レコードの複数のフィールドを更新します。 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 }
>

型エイリアス

型エイリアスは、レコードのスキーマを定義します。 つまり、タイプエイリアスは、レコードが保存できるフィールドと、これらのフィールドが保存できる値のタイプを定義します。 したがって、プログラマーは、値を割り当てる際に特定の属性を見逃すことはありません。

構文

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

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
>

ここで、場所と年齢を入力するのを忘れた場合、ステートメントは場所と年齢のフィールドの入力パラメーターを持つ関数を返します。

> 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

エルム-エラー処理

エラーは、プログラム内の予期しない状態です。 エラーは、コンパイル時または実行時に発生する可能性があります。 コンパイル時エラーは、プログラムのコンパイル中に発生し(たとえば、プログラムの構文のエラー)、実行時エラーはプログラムの実行中に発生します。 他のプログラミング言語とは異なり、Elmはランタイムエラーをスローしません。

ユーザーの年齢を受け入れるアプリケーションを検討してください。 年齢がゼロまたは負の場合、アプリケーションはエラーをスローする必要があります。 この場合、ユーザーが年齢としてゼロまたは負の値を入力すると、Elmアプリケーションはエラー処理の概念を使用して、実行時に明示的にエラーを発生させることができます。 エラー処理は、プログラムの実行中に予期しないことが発生した場合のアクションを指定します。

エルムプログラミング言語は、次の方法でエラーを処理します-

  • 多分
  • 結果

多分

アプリケーションの検索機能を検討してください。 検索キーワードが見つかった場合、検索関数は関連データを返します。それ以外の場合は何も返しません。 このユースケースは、MayBeタイプを使用してElmに実装できます。

構文

variable_name:MayBe data_type

タイプMayBeの変数は、次の値のいずれかを含めることができます-

  • Just some_Value-有効なデータがある場合に使用されます。
  • Nothing-値が存在しないか不明な場合に使用されます。 他のプログラミング言語ではnullと同等のものはありません。

次の例は、変数と関数でMayBe型を使用する方法を示しています。

ステップ1 *- *MayBeDemo.elm ファイルを作成し、次のコードを追加します

-- 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
  • ステップ2 *-elm replでモジュールをインポートし、以下のように実行します
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

関数は、関数に渡された値がインド、中国、またはスリランカであるかどうかをチェックします。 パラメータの値がこれらのいずれとも一致しない場合、何も返しません。

結果

アプリケーションが何らかの条件を検証し、条件が満たされない場合にエラーを発生させる必要がある例を考えてみましょう。 これを実現するために、結果タイプを使用できます。 アプリケーションが明示的にエラーを発生させ、問題の詳細を返す必要がある場合は、結果タイプを使用する必要があります。

構文

Result型の宣言には、エラーのデータ型(通常はString)と、すべて正常に終了した場合に返される結果のデータ型の2つのパラメーターが必要です。

type Result error_type data_value_type
= Ok data_value
| Err error_message

結果タイプは、次の値のいずれかを返します-

  • Ok some_value-返される結果を表します
  • Err-予想される条件が満たされていない場合に返されるエラーメッセージを表します。

イラスト1

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

渡されたパラメーターが有効な場合、String.toInt関数は整数値を返します。 パラメータが数値でない場合、関数はエラーを返します。

イラスト2

次の例では、年齢をパラメーターとして受け入れます。 この関数は、年齢が0〜135の場合に年齢を返し、それ以外の場合は適切なエラーメッセージを返します。

  • ステップ1 *-ResultDemo.elmファイルを作成し、次のコードを追加します。
--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
  • ステップ2 *-モジュールをelmパッケージにインポートし、以下のように実行します
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

ニレ-建築

この章では、Elmプラットフォームでアプリケーションを作成する標準的な方法について説明します。 Elmは、Model-View-Controllerパターンに類似したアーキテクチャパターンを使用します。

以下は、Elm Architectureの4つの主要部分です。

  • モデル
  • View
  • メッセージ
  • 更新

アーキテクチャ

Elmアーキテクチャの仕組み

*model* にはアプリケーションの状態が含まれます。 たとえば、アプリケーションが顧客のリストを表示する場合、状態には各顧客データが含まれます。 状態を表示可能な方法で表示するには、 *view*/htmlを生成する必要があります。 ユーザーがボタンを押すか、フォームにデータを入力してビューと対話すると、ビューは *messages* と呼ばれる信号を生成します。 メッセージは *update* メソッドに渡されます。このメソッドはメッセージを評価し、適切なアクションを実行します。 したがって、更新メソッドは新しいモデルを生成します。

新しいモデルは新しいビューを生成します。 このビューは、ユーザーからのメッセージへの新しい相互作用につながり、更新機能に進みます。 さらに、関数は新しいモデルを作成します。 したがって、上記の図に示すように、サイクルが繰り返されます。

モデル

モデルはアプリケーションの状態を扱います。 モデルを定義するための構文は以下のとおりです-

-- Model syntax

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

モデルを作成するには、最初に必要なすべてのプロパティを持つテンプレートを作成する必要があります。 各プロパティは、アプリケーションの状態を指定します。

View

ビューは、アプリケーションの状態を視覚的に表現したものです。 ビューは、データを取得し、そこからWebページを生成する方法を知っています。 ユーザーがビューと対話するとき、ユーザーはメッセージを生成して状態を操作できます。 ビューを定義するための構文は以下のとおりです-

--View Syntax
view model =some_implementation

メッセージ

メッセージは、アプリケーションの状態を変更するためのユーザーからのリクエストです。 メッセージはパラメーターとして更新関数に渡されます。

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

構文は、タイプMessageを示しています。 elmアプリケーションは、渡されたメッセージに基づいて状態を編集します。 これらの決定は、更新メソッドで行われます。

更新

更新機能は、パラメーターとして渡されるメッセージを解釈し、モデルを更新します。

--Update Syntax
update Message_type model =
   some_implementation

更新関数は、パラメーターとして Message とModelを取ります。

エルム-パッケージマネージャー

パッケージマネージャーは、アプリケーションのパッケージのインストール、アップグレード、構成、および削除のプロセスを自動化するコマンドラインツールです。

JavaScriptにnpmというパッケージマネージャーがあるように、elmには_elm-package_というパッケージマネージャーがあります。

パッケージマネージャは、次の3つのタスクを実行します-

  • elmアプリケーションに必要なすべての依存関係をインストールします
  • カスタムパッケージを公開します
  • 公開および更新の準備ができたときに、パッケージのバージョンを決定します。

Elm Package Managerコマンド

次の表は、さまざまなElmパッケージマネージャーコマンドの一覧です-

Sr. No. Command Syntax Description
1 install elm-package install Installs packages to use locally
2 publish elm-package publish Publishes your package to the central catalog
3 bump elm-package bump Bumps version numbers based on API changes
4 diff elm-package diff Gets differences between two APIs

パッケージを公開するには、GitHubでソースコードをホストし、バージョンにgitタグが適切にラベル付けされている必要があります。 次の図は、elm-package managerを使用して外部依存関係をプルする方法を示しています。

図-svgパッケージのインストール

この例では、Scalable Vector Graphics(SVG)をelmアプリケーションに統合する方法を説明します。

  • ステップ1 *-フォルダーelmSvgAppを作成する
  • ステップ2 *-次のコマンドを使用してsvgパッケージをインストールします-
elm-package install elm-lang/svg
  • ステップ3 *-インストールSvgDemo.elmファイルを作成し、以下の内容を入力します。 Svgモジュールをインポートして、_100x100_次元の長方形を描画し、赤色を塗りつぶします。
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"
      ]
      []
   ]
  • ステップ4 *-elm make。\ SvgDemo.elmを使用してプロジェクトをビルドします。 これは以下に示すようにindexlを生成します-

プロジェクトのビルド

エルム-メッセージ

メッセージはElmアーキテクチャのコンポーネントです。 これらのコンポーネントは、アプリケーションのインターフェイスとのユーザーの対話に応じて、ビューによって生成されます。 メッセージは、アプリケーションの状態を変更するユーザー要求を表します。

構文

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

イラストレーション

次の例は、単純なカウンターアプリケーションです。 ユーザーが[追加]ボタンと[減算]ボタンをクリックすると、アプリケーションは変数の値をそれぞれ1ずつ増やしたり減らしたりします。

アプリケーションには4つのコンポーネントがあります。 コンポーネントは以下のとおりです-

メッセージ

この例のメッセージは次のようになります-

type Message = Add | Subtract

モデル

モデルは、アプリケーションの状態を表します。 カウンターアプリケーションでは、モデル定義を以下に示します。カウンターの初期状態はゼロになります。

model = 0

View

ビューは、アプリケーションの視覚要素を表します。 ビューには2つのボタン()と(-)が含まれます。 ユーザーがそれぞれ「」ボタンと「-」ボタンをクリックすると、「追加」および「減算」メッセージがビューによって生成されます。 その後、モデルの変更された値がビューに表示されます。

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

更新

このコンポーネントには、ビューによって生成された各メッセージに対して実行されるコードが含まれています。 これは以下の例に示されています-

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

すべてを一緒に入れて

  • ステップ1 *-フォルダー_MessagesAppとファイルMessagesDemo.elm_を作成します
  • ステップ2 *-次のコードをelmファイルに追加します-
import Html exposing (..)
import Html.Events exposing(onClick)

model = 0 -- Defining the Model

--Defining the View

view model =
   h1[]
   [  div[] [text "CounterApp from finddevguides" ]
      ,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
   }

ステップ3 *-ターミナルで elm makeコマンド*を実行します。 * elm makeコマンド*はコードをコンパイルし、上記で作成した.elmファイルからHTMLファイルを生成します。

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 indexl

ステップ4 *- *indexl を開き、以下のように機能することを確認します-

elm makeコマンド

Elm-コマンド

前の章では、Elmアーキテクチャのさまざまなコンポーネントとその機能について説明しました。 ユーザーとアプリケーションは、メッセージを使用して互いに通信します。

アプリケーションが外部サーバー、API、マイクロサービスなどの他のコンポーネントと通信する必要がある例を考えてみましょう。 ユーザーリクエストを処理します。 これは、Elmのコマンドを使用して実現できます。 メッセージとコマンドは同義ではありません。 メッセージはエンドユーザーとアプリケーション間の通信を表し、コマンドはElmアプリケーションが他のエンティティと通信する方法を表します。 コマンドは、メッセージに応答してトリガーされます。

次の図は、複雑なElmアプリケーションのワークフローを示しています-

ワークフロー

ユーザーはビューと対話します。 ビューは、ユーザーのアクションに基づいて適切なメッセージを生成します。 更新コンポーネントはこのメッセージを受信し、コマンドをトリガーします。

構文

コマンドを定義するための構文は以下のとおりです-

type Cmd msg

ビューによって生成されたメッセージはコマンドに渡されます。

次の例では、APIにリクエストを作成し、APIからの結果を表示します。

アプリケーションはユーザーから番号を受け取り、それをNumbers APIに渡します。 このAPIは、数値に関連する事実を返します。

アプリケーションのさまざまなコンポーネントは次のとおりです-

Httpモジュール

ElmのHttpモジュールは、HTTPリクエストの作成と送信に使用されます。 このモジュールはコアモジュールの一部ではありません。 このパッケージをインストールするには、elmパッケージマネージャーを使用します。

API

この例では、アプリケーションはNumbers APIと通信します(「http://numbersapi.com/#42」)。

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

モデル

モデルは、ユーザーが入力した値と、APIによって返される結果を表します。

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

メッセージ

アプリケーションには、次の3つのメッセージがあります-

  • ShowFacts
  • 入力
  • NewFactArrived

_Show Facts_ボタンをクリックすると、_ShowFacts_メッセージが更新メソッドに渡されます。 ユーザーがテキストボックスに値を入力すると、_Input_メッセージがupdateメソッドに渡されます。 最後に、Httpサーバーの応答を受信すると、_NewFactArrived_メッセージが更新に渡されます。

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

更新

updateメソッドは、モデルとコマンドオブジェクトを含むタプルを返します。 ユーザーが[ファクトの表示]ボタンをクリックすると、メッセージが更新プログラムに渡され、更新プログラムが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)

ヘルパー機能

ヘルパー関数_getRandomNumberFromAPI_はNumbersAPIを呼び出し、ユーザーが入力した番号をそれに渡します。 APIによって返された結果は、モデルの更新に使用されます。

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

これがElmプロジェクトのエントリポイントです。

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

すべてを一緒に入れて

  • ステップ1 *-CommandAppフォルダーとCommandDemo.elmファイルを作成します。
  • ステップ2 *-コマンド_elm package install elm-lang/http_を使用してhttpモジュールをインストールします。
  • ステップ2 *-以下に示すようにCommandDemo.elmの内容を入力します-
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)
  • ステップ4 *-コマンドを実行します。
C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm

これにより、以下に示すようにhtmlファイルが生成されます。

htmlを生成

エルム-サブスクリプション

前の章で、ビューがコマンドを使用して他のコンポーネントと対話することについて説明しました。 同様に、コンポーネント(E.g. WebSocket)は、サブスクリプションを使用してビューと通信できます。 サブスクリプションは、Elmアプリケーションがキーボードイベント、タイマーイベント、WebSocketイベントなどの外部入力を受信できる方法です。

次の図は、Elmアプリケーションでのサブスクリプションの役割を説明しています。 ユーザーは、メッセージを介してElmアプリケーションと対話します。 指定されたアプリケーションはWebSocketを使用し、2つの操作モードがあります-

  • コマンドを使用してクライアント側のデータをソケットサーバーに送信する
  • サブスクリプション経由でソケットサーバーからいつでもデータを受信する

ソケットサーバー

構文

サブスクリプションを定義するための構文は以下のとおりです-

type Sub msg

簡単な例を使用してサブスクリプションを理解しましょう。

以下の例では、アプリケーションはサーバーにメッセージを送信します。 サーバーはエコーサーバーで、同じメッセージでクライアントに応答します。 すべての受信メッセージは、後でリストに表示されます。 WebSocket(wssプロトコル)を使用して、サーバーからのメッセージを継続的にリッスンできるようにします。 WebSocketはコマンドを使用してサーバーにユーザー入力を送信し、サブスクリプションを使用してサーバーからメッセージを受信します。

アプリケーションのさまざまなコンポーネントを以下に示します-

エコーサーバー

エコーサーバーには、wssプロトコルを使用してアクセスできます。 エコーサーバーは、ユーザー入力をアプリケーションに送り返します。 エコーサーバーを定義するためのコードは次のとおりです-

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

モデル

モデルは、ユーザー入力と、ソケットサーバーからの着信メッセージのリストを表します。 モデルを定義するためのコードは以下のとおりです-

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

メッセージ

メッセージタイプには、ユーザーからテキスト入力を取得するための入力が含まれます。 ユーザーがボタンをクリックしてWebSocketサーバーにメッセージを送信すると、送信メッセージが生成されます。 NewMessageは、エコーサーバーからメッセージが到着したときに使用されます。

type Msg
   = Input String
   | Send
   | NewMessage String

View

アプリケーションのビューには、ユーザー入力をサーバーに送信するためのテキストボックスと送信ボタンが含まれています。 サーバーからの応答は、_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 ]

更新

更新機能は、メッセージとモデルコンポーネントを受け取ります。 メッセージタイプに基づいてモデルを更新します。

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.

購読

サブスクリプション関数は、モデルオブジェクトを受け取ります。 WebSocketサーバーからメッセージを受信するには、_WebSocket.listen_を呼び出して、メッセージを_NewMessage_として渡します。 サーバーから新しいメッセージが届くと、updateメソッドが呼び出されます。

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

main

主な機能は、次に示すようにelmアプリケーションへのエントリポイントです。

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

すべてを一緒に入れて

  • ステップ1 *-ディレクトリSubscriptionAppを作成し、ファイルSubscriptionDemo.elmを追加します。
  • ステップ2 *-次の内容を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 ]
  • ステップ3 *-elmパッケージマネージャーを使用してwebsocketsパッケージをインストールします。
C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket
  • ステップ4 *-以下に示すように、indexlファイルをビルドして生成します。
C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm
  • ステップ5 *-実行すると、次の出力が生成されます-

SubscriptionApp