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
Elm 入門演習 -- Type_html/css_WEB-ITnose
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 の型シグネチャは次のように記述する必要があります... 塊: 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 : String -> {name: String, age: Int} -> {name: String, age: Int}
Union 型は、Elm 型システムの最も重要な部分の 1 つです。可能な値のセットの場合、各 A 値は次のようにタグと呼ばれます:
type Bool = True | Falsetype User = Anonymos | Authed
ログイン後にコピー
その中で、True と False、Anonymos と Authed はすべてタグ名です (type Bool = True | Falsetype User = Anonymos | Authed
Tag は Type ではないことに注意してください
)。列挙に似ていますか?それだけでなく、Union 型の利点は、Tag が既知の型のセットを保持できることです。上記のコードでは 2 つのタイプのユーザーを区別できますが、現時点では、認証されたユーザーの名前を取得することはできません。既知のタイプを Tag と組み合わせて次のように表現できます。
type User = Anonymos | Authed String
> type User = Anonymous | Authed String> AnonymousAnonymous : User> AuthedAuthed : String -> User
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
では、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

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック











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

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

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

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

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

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

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

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