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 StringUnion タイプを作成するとき、実際にはタグごとに共用体型を作成します。対応する値コンストラクターが作成されます:
> 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
型変数
型のリストについては上で説明しましたが、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

HTMLの役割は、タグと属性を使用してWebページの構造とコンテンツを定義することです。 1。HTMLは、読みやすく理解しやすいようなタグを介してコンテンツを整理します。 2。アクセシビリティとSEOを強化するには、セマンティックタグなどを使用します。 3. HTMLコードの最適化により、Webページの読み込み速度とユーザーエクスペリエンスが向上する可能性があります。

HTML、CSS、およびJavaScriptは、Web開発の3つの柱です。 1。HTMLは、Webページ構造を定義し、などなどのタグを使用します。2。CSSは、色、フォントサイズなどのセレクターと属性を使用してWebページスタイルを制御します。

HTMLはWeb構造を定義し、CSSはスタイルとレイアウトを担当し、JavaScriptは動的な相互作用を提供します。 3人はWeb開発で職務を遂行し、共同でカラフルなWebサイトを構築します。

HTMLは、簡単に学習しやすく、結果をすばやく見ることができるため、初心者に適しています。 1)HTMLの学習曲線はスムーズで簡単に開始できます。 2)基本タグをマスターして、Webページの作成を開始します。 3)柔軟性が高く、CSSおよびJavaScriptと組み合わせて使用できます。 4)豊富な学習リソースと最新のツールは、学習プロセスをサポートしています。

Anexampleapalofastartingtaginhtmlis、それはaperginsaparagraph.startingtagsaresentionentientiontheyinitiateelements、definetheirtypes、およびarecrucialforurturingwebpagesandcontingthomedomを構築します。

メニューで点線のラインセグメンテーション効果を設計する方法は?メニューを設計するときは、通常、皿の名前と価格の間に左右に合わせることは難しくありませんが、真ん中の点線またはポイントはどうですか...

WebコードエディターのHTML要素分析では、多くのオンラインコードエディターを使用すると、ユーザーはHTML、CSS、およびJavaScriptコードを入力できます。最近、誰かが提案した...


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

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

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

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。
