Haskell型システムによるブレードランナの世界のモデリング



あなたがHaskell旅行を始めているならば、私はあなたがタイプシステムに集中することを示唆します.
タイプはあなたのHaskell知識が成長するルーツです.
Haskellは代数的データ型を持っている.これは、他の型の複合体である型を作ることができるということを言うのには空想的な方法です.直感的に、型の値の集合と考えることができます.
代数的データ型による架空の刃ランナー宇宙の簡単な人口統計学をモデル化しましょう.

複製


Replicantsは、人間と実質的に同一である生物工学的な存在です.
レプリケートのすべてのモデルを表すタイプを定義しましょう.
newtype Replicant = ReplicantModel SerialNumber deriving Show
Serial Number のような指定されたレプリケートモデルの一意のIDを表す文字列です"N6MAA10816" .deriving Show 最後に、「自動的に値を印刷可能にする」ことを意味します.
今、我々は我々の複製物のアイデンティティを表すタイプを必要とします.
newtype SerialNumber = SerialNumber String deriving Show
を使用して新しい型を作成するときnewtype or data すべての左のキーワード= 型宣言では、型の世界に住んでいます.の間、データコンストラクタは= パラメータとして他の型を取ります.
型宣言でSerialNumber はデータコンストラクターで、String型のパラメーターを持ちます.
意味は、型ストリングの値を私に与えます、そして、私はタイプSerialNumber .
データコンストラクタには引数がない場合があります.
それは見て混乱することができますSerialNumber String .
データコンストラクターを宣言するたびに、常に引数の種類を指定します.
実際にデータコンストラクターを使用したい場合は、値を適用します.
> SerialNumber "N6FAB61216"
SerialNumber "N6FAB61216"
名前は何ですか.我々が他の名前によってバラと呼ぶそれは、甘いにおいがします.
タイプ宣言のために、私たちはデータコンストラクタのための引数のタイプをリストします、そして、我々が欲しいとき
データを実際に構築するには、値を適用します.
種類と価値は異なる世界に存在する
任意のHaskell開始儀式で成功する最初のキーは、式がコンテクストによって判断される型か値かを理解することです.
それで、あらゆるタイプ宣言は私たちに新しいタイプ建設者と少なくとも一つの新しいデータ建設者を与えます.
このことを心に留めてReplicant 再びタイプ.
newtype Replicant = ReplicantModel SerialNumber deriving Show
Replicant のコンストラクタです= . 価値の世界の側の右手にReplicantModel これはデータコンストラクタです.データコンストラクターは単なる関数です.
シリアルナンバーを作りましょう.
> SerialNumber
<interactive>: error:
     No instance for (Show (String -> SerialNumber))
        arising from a use of print
        (maybe you haven't applied a function to enough arguments?)
     In a stmt of an interactive GHCi command: print it
私の災難はあなたの理解への贈り物です.
具体的な値がなければ、私たちは印刷することができます.完全に適用されたデータコンストラクタの評価から、具体的な値しか得られません.
このメッセージのキーは、データコンストラクタSerialNumber は、関数の型を持つ部分のみを意味する.
データコンストラクターは単なる関数です.
特に部分的に適用されるタイプシグネチャSerialNumber isString -> SerialNumberデータコンストラクターは、SerialNumber データ建設者.
この「適用」とは、すべてのパラメータが具体的な値を与えられたことを意味する.シリアル番号が部分的に適用された私の誤植とは対照的に.
例えば、
> add :: Int -> Int -> Int
> add a b = a + b
その後、部分的に適用することができますadd
> let x = add 1
関数を印字できないことに注意してください.
または完全に適用することができますadd
> add 1  1
2
通常の関数と同じように、データコンストラクターには、パラメーターに“適用される”値があります.
他の奇妙な/通常の言語に精通している人々は、通常これを引数で関数を呼ぶとして、あなたが知っているものを忘れると言います.
価値の世界にこの新しいレプリカモデルを誕生しましょう.
> ReplicantModel (SerialNumber "KD6-3.7")
ReplicantModel (SerialNumber "KD6-3.7")

人間


我々はそれをしている間、我々は人間を識別するためのタイプが必要です.
人間に発音名を与えるのは慣習です.
newtype Name = Name String deriving Show
私たちの型とデータのコンストラクタの両方が「名前」と呼ばれているという事実に注意してください.
これはあなたを混乱させないでください.
Haskellコンパイラは、コンテキストWorldまたはType World内にあるかどうかをコンテキストから推論でき、“Replicant”または“Human”が評価されるたびに使用するいずれかを決定します.
左側にName 型を表す型コンストラクターです.右側にはデータコンストラクタもありますName は値を表す.
これはHaskellで多く起こり、それらを開始することを混乱させます.
今、人間を表現するためのタイプを作ることができます.ヒアName typeコンストラクタによって、Person データ建設者.
newtype Human = Person Name deriving Show
タイプの完全適用された人価値を得るためにHuman 私たちが実際に使用することができます私たちは私たちのタイプ名の値を適用するPerson データ建設者.
> Person (Name "Deckard")
Person (Name "Deckard"
今、我々は完全に我々は実際に使用できるタイプの人間の値を持っているデータコンストラクターを適用している.
私たちは、タイプが人間であると確認することができます:t Haskellインタプリタのコマンド.
> :t Person (Name "Deckard")
Human

市民


我々は今、すべての種のセットを表すために新しい複合型を形成することができます.
data Species = ReplicantSpecies Replicant | HumanSpecies Human deriving Show
二つの種があるからReplicant and Human , 種型は2つのデータコンストラクタを持つ.注意| 彼らの間で.これは「どちらか」という意味です.
平易な英語では、型の値はどちらのタイプの値からも成り立つReplicant or Human .
彼らの種と彼らの出生年による市民を分類する時間は、どんな世話をする州のようにでもします.
data Citizen = Citizen Species BirthYear deriving Show
我々Citizen type 1つのデータコンストラクタも呼び出されますCitizen には2つのパラメータがあります.最初の値は、値Species . 2番目のパラメータはBirthYear
次に何が来るか推測できます.
newtype BirthYear = Year Int deriving Show
それで、我々はそれを持ちます.この孤独な惑星で我々の最初の市民をつくってください.
> let replicant = ReplicantSpecies (ReplicantModel (SerialNumber "LUV"))
> Citizen replicant (Year 2035)
Citizen (ReplicantSpecies (ReplicantModel (SerialNumber "LUV"))) (Year 2035)

"He named you. Must be special." - K


> let species = ReplicantSpecies (ReplicantModel (SerialNumber "LUV"))
> :t species
Replicant
> :t Citizen species (Year 2035)
Citizen
そこにあります.タイプシステムについて学ぶ最良の方法は、代数的なデータ型を使用してドメインをモデル化し、それらを再生することです.使用する:t コマンドハスケルghci 式の型を参照してください.
次のステップは、製品タイプとサムタイプの違いを理解することです.これらのアイデアの両方を把握すると、この記事の理解を深めることになります.
この記事のコードは、オンラインREPLhere .