目次
も可能です。 Elm は型シグネチャと呼ばれ、コロン: を使用して型を示します。Hello world に基づいて、変数と関数をそれぞれ定義し、型を示します
基本型
基本型はほとんどの言語に似ており、String、Char、Bool Int、Float にすぎません。公式 Web サイトのリテラルを参照できます。 Elm では、String は二重引用符を使用する必要があり、Char を表すには単一引用符を使用する必要があることに注意してください。
厳密に言えば、List は型ではありません。その型は List a です。ここで、a は型変数と呼ばれます。これは、List がコンテナであり、String、Int、または何も保持できないため、型は次のとおりである必要があります。動的:
type alias Name = Stringtype alias Age = Int  type alias User = {name: Name, age: Age}user : Useruser =  { name = "Zhang zhe", age = 89 }  setUserName : String -> User -> UsersetUserName name user = {user | name = name}
ログイン後にコピー
" >
type alias Name = Stringtype alias Age = Int  type alias User = {name: Name, age: Age}user : Useruser =  { name = "Zhang zhe", age = 89 }  setUserName : String -> User -> UsersetUserName name user = {user | name = name}
ログイン後にコピー
type Bool = True | Falsetype User = Anonymos | Authed
ログイン後にコピー
" >
type Bool = True | Falsetype User = Anonymos | Authed
ログイン後にコピー
Counter with type
总结
ホームページ ウェブフロントエンド htmlチュートリアル Elm 入門演習 -- Type_html/css_WEB-ITnose

Elm 入門演習 -- Type_html/css_WEB-ITnose

Jun 24, 2016 am 11:15 AM

Facebook がかつてコミュニティ イベントで、Javascript をどんどん使っていくうちに、すぐに PHP で遭遇したのと同じ問題に直面するようになった、と言ったのを覚えています。

動的言語は諸刃の剣のようなもので、その柔軟性を気に入っていただける一方で、小さな見落としによって大きな損失を被る可能性もあります。 Elm は、通常、ほとんどの関数型言語で選択される静的強力な型付けを選択しました。オブジェクト指向言語のクラスの概念がなければ、強力な型システムがすべての「これは何ですか?」という質問を解決する役割を果たします

型アノテーション

も可能です。 Elm は型シグネチャと呼ばれ、コロン: を使用して型を示します。Hello world に基づいて、変数と関数をそれぞれ定義し、型を示します

import Html exposing (..)import Html.Attributes exposing (..)elm : Stringelm = "elm"sayHello : String -> StringsayHello name =   "Hello, " ++ namemain =  div [class "hello"]     [ span [] [text (sayHello elm)]    ]
ログイン後にコピー

elm "elm" の値を数値に変更して見てください。それが機能する場合、何が起こったのでしょうか?

Detected errors in 1 module.-- TYPE MISMATCH ---------------------------------------------------------------The type annotation for `elm` does not match its definition.5| elm : String         ^^^^^^The type annotation is saying:    StringBut I am inferring that the definition has this type:    number
ログイン後にコピー

コンパイラはエラーを見つけ、特定の行番号を見つけることができました。

型が宣言されていない場合はどうなりますか?型アノテーション

import Html exposing (..)import Html.Attributes exposing (..)--elm : Stringelm = 6--sayHello : String -> StringsayHello name =   "Hello, " ++ namemain =  div [class "hello"]     [ span [] [text (sayHello elm)]    ]
ログイン後にコピー

をコメントアウトして再コンパイルすると、引き続きエラーが報告されますが、エラー メッセージが変更されています。今回は 14 行目です:

Detected errors in 1 module.-- TYPE MISMATCH ---------------------------------------------------------------The argument to function `sayHello` is causing a mismatch.14|                      sayHello elm)                                  ^^^Function `sayHello` is expecting the argument to be:    StringBut it is:    number
ログイン後にコピー

明示的な型アノテーションがなくても、Elm の型推論システムはこれは型推論により、sayHello 関数のパラメータは文字列であるはずだと考えられますが、数値が渡されるため、エラーが報告されます。

2 つの異なるエラー プロンプトを比較すると、型アノテーションによりコンパイラーがエラーをより正確に見つけて特定できることがわかります。学習が進むにつれて、型システムによってもたらされる安心感が徐々に好きになるでしょう。コンパイルが失敗した場合、明確なプロンプトが表示されるため、問題をすぐに特定できます。そして、コンパイルが成功する限り、プログラムは確実に実行されます。

基本型とList

基本型

基本型はほとんどの言語に似ており、String、Char、Bool Int、Float にすぎません。公式 Web サイトのリテラルを参照できます。 Elm では、String は二重引用符を使用する必要があり、Char を表すには単一引用符を使用する必要があることに注意してください。

List

厳密に言えば、List は型ではありません。その型は List a です。ここで、a は型変数と呼ばれます。これは、List がコンテナであり、String、Int、または何も保持できないため、型は次のとおりである必要があります。動的:

> [ "Alice", "Bob" ][ "Alice", "Bob" ] : List String> [ 1.0, 8.6, 42.1 ][ 1.0, 8.6, 42.1 ] : List Float> [][] : List a
ログイン後にコピー

型変数については後で引き続き説明します。ここで覚えておく必要があることは 1 つだけです。

List は型ではなく、List String のようなものは

です。 パラメータが 1 つしかないため、Elm の List は 1 つの型の要素のみを収容できます。Javascript の List とは異なり、すべての要素を受け入れます。次のものがコンパイラによって検出され、報告されます。

list = [1, "a"]
ログイン後にコピー

型エイリアス

使用される型エイリアス

type alias Name = Stringtype alias Age = Int  type alias User = {name: Name, age: Age}user : Useruser =  { name = "Zhang zhe", age = 89 }  setUserName : String -> User -> UsersetUserName name user = {user | name = name}
ログイン後にコピー

などの既知の型を組み合わせたり再利用したりするため、基本的な型にビジネス セマンティクスを持たせるだけでなく、複雑なデータ構造に適したセマンティクス型を組み合わせることができます。エイリアスがない場合、setUserName の型シグネチャは次のように記述する必要があります... 塊:

setUserName : String -> {name: String, age: Int} -> {name: String, age: Int}
ログイン後にコピー

Union 型

Union 型は、Elm 型システムの最も重要な部分の 1 つです。可能な値のセットの場合、各 A 値は次のようにタグと呼ばれます:

type Bool = True | Falsetype User = Anonymos | Authed
ログイン後にコピー

その中で、True と False、Anonymos と Authed はすべてタグ名です (

Tag は Type ではないことに注意してください

)。列挙に似ていますか?それだけでなく、Union 型の利点は、Tag が既知の型のセットを保持できることです。上記のコードでは 2 つのタイプのユーザーを区別できますが、現時点では、認証されたユーザーの名前を取得することはできません。既知のタイプを Tag と組み合わせて次のように表現できます。

type User = Anonymos | Authed String
ログイン後にコピー
Union タイプを作成するとき、実際にはタグごとに共用体型を作成します。対応する値コンストラクターが作成されます:
> type User = Anonymous | Authed String> AnonymousAnonymous : User> AuthedAuthed : String -> User
ログイン後にコピー

他の情報のない匿名は値として直接使用できますが (True と False を考えてください)、既知の型を持つ Authed は実際には受け入れる関数です。文字列を返し、ユーザータイプ:

users : List Userusers = [  Anonymous,   Authed "Kpax"]
ログイン後にコピー

Haskell にはタグの名前はありません。これに似たものは値コンストラクターと呼ばれ、その目的を直接示します: この型の値を構築するため

タグは分解することもできます :

getAuthedUserName : User -> StringgetAuthedUserName user =  case user of     Anonymous ->      ""    Authed name ->      name
ログイン後にコピー

この関数は、認証されたユーザーの名前を返します。匿名ユーザーの場合は空の文字列を返します。

オンライン エディターで実行できる完全なコードは次のとおりです:

import Html exposing (..)import Listtype User = Anonymous | Authed Stringusers : List Userusers = [  Anonymous,   Authed "Kpax",  Authed "qin"]getAuthedUserName : User -> StringgetAuthedUserName user =  case user of     Anonymous ->      ""    Authed name ->      name      main =  div [] (List.map (text << getAuthedUserName) users)
ログイン後にコピー

text << getAuthedUserName は、lodash の _ と同様に、Elm の << 演算子を使用します。 flowRight 関数

型変数

型のリストについては上で説明しましたが、a は型変数であり、オブジェクト指向プログラミングにおけるジェネリックスの概念と同様に、現在不確実な型を表します

型シグネチャマップ関数の Type 変数も使用されます:

map : (a -> b) -> a -> b
ログイン後にコピー

これにより、ユーザーの型が User である限り、map 関数は特定の型を気にせずに、map userToString user を呼び出すことができます。

では、List a 型を定義するにはどうすればよいでしょうか?コードは次のとおりです

type List a = Empty | Node a (List a)
ログイン後にコピー

前面说到 Tag可以携带已知类型,那么是否可以携带正在定义的这个类型呢?答案是肯定的!这就是类型的 递归, List a就是这样一个带有类型参数的递归类型,平时我们写的数组,可以理解为如下代码的语法糖

-- []Empty-- [1]Node 1 Empty-- [1, 2, 3]Node 1 (Node 2 (Node 3 Empty))
ログイン後にコピー

同样的思路,我们完全可以自己实现二叉树等数据结构,有兴趣的朋友不妨试试,官方文档有 相关章节可供参考

Counter with type

上一章[基础篇]()我们讲了Counter的实现,代码如下:

import Html exposing (..)import Html.Events exposing (onClick)import Html.App as Apptype Msg = Increment | Decrementupdate msg model =   case msg of     Increment ->       model + 1    Decrement ->      model - 1view model =  div []    [ button [onClick Decrement] [text "-"]    , text (toString model)    , button [onClick Increment] [text "+"]  ]initModel = 3main = App.beginnerProgram {model = initModel, view = view, update = update}
ログイン後にコピー

让我们用刚刚学习的知识给以上代码添加类型和类型注解

首先,我们有 initModel这个数据,它的类型是 Int,不具备任何业务语义,让我们定义一个类型别名 Model来表示Counter的数据

type alias Model = Int
ログイン後にコピー

自然 initModel的类型应该为 Model

initModel : ModelinitModel = 3
ログイン後にコピー

update函数的类型签名比较简单,它接受消息 Msg和当前数据 Model,返回新的数据 Model:

update : Msg -> Model -> Model
ログイン後にコピー

view函数接受 Model类型的数据,返回什么呢?如果查阅 div函数的 文档,你会发现返回的是一个带有类型变量的类型 Html msg。其实很好理解,因为渲染界面的函数不仅要输出Html,当事件发生时还要输出 消息,输出消息的类型,就是应该赋给变量 msg的类型,在 Counter中消息的类型是 Msg,因此:

view : Model -> Html Msg
ログイン後にコピー

完整代码:

import Html exposing (..)import Html.Events exposing (onClick)import Html.App as Apptype alias Model = Inttype Msg = Increment | Decrementupdate : Msg -> Model -> Modelupdate msg model =   case msg of     Increment ->       model + 1    Decrement ->      model - 1view : Model -> Html Msgview model =  div []    [ button [onClick Decrement] [text "-"]    , text (toString model)    , button [onClick Increment] [text "+"]  ]initModel : ModelinitModel = 3main = App.beginnerProgram {model = initModel, view = view, update = update}
ログイン後にコピー

总结

类型的学习可能有些枯燥,但是非常重要。如果你了解redux,你会发现Union type简直天生就是做action的料,比起redux在javascript中使用的字符串既简洁又达意,甚至还可以嵌套组合,谈笑风生!高到不知道哪里去了!

下一章我们将把在线编辑器放到一边,把Counter迁移到本地运行,然后实现一个CounterList,在CounterList中,你会看到Elm是如何复用组件,以及为什么Elm被称为理想的 分形架构。

各种架构对比,可以参考Cycle.js作者Andre Staltz的 文章 `elm

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? 公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? Mar 04, 2025 pm 12:32 PM

公式アカウントのWebページはキャッシュを更新します。これはシンプルでシンプルで、ポットを飲むのに十分な複雑です。あなたは公式のアカウントの記事を更新するために一生懸命働きましたが、ユーザーはまだ古いバージョンを開くことができますか?この記事では、この背後にあるtwist余曲折と、この問題を優雅に解決する方法を見てみましょう。それを読んだ後、さまざまなキャッシュの問題に簡単に対処でき、ユーザーが常に新鮮なコンテンツを体験できるようになります。最初に基本について話しましょう。それを率直に言うと、アクセス速度を向上させるために、ブラウザまたはサーバーはいくつかの静的リソース(写真、CSS、JSなど)やページコンテンツを保存します。次回アクセスするときは、もう一度ダウンロードすることなく、キャッシュから直接検索できます。自然に高速です。しかし、このことは両刃の剣でもあります。新しいバージョンはオンラインです、

WebページのPNG画像にストローク効果を効率的に追加する方法は? WebページのPNG画像にストローク効果を効率的に追加する方法は? Mar 04, 2025 pm 02:39 PM

この記事では、CSSを使用したWebページへの効率的なPNG境界追加を示しています。 CSSはJavaScriptやライブラリと比較して優れたパフォーマンスを提供し、微妙または顕著な効果のために境界幅、スタイル、色を調整する方法を詳述していると主張しています

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

&lt; Progress&gt;の目的は何ですか 要素? &lt; Progress&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:34 PM

この記事では、HTML&lt; Progress&gt;について説明します。要素、その目的、スタイリング、および&lt; meter&gt;との違い要素。主な焦点は、&lt; Progress&gt;を使用することです。タスクの完了と&lt; Meter&gt; statiの場合

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

See all articles