web-dev-qa-db-ja.com

HaskellのDataKinds拡張機能とは何ですか?

私は Learn You a Haskell を読んだだけで得られたので、意味のあるDataKinds拡張機能の説明を見つけようとしています。私が学んだ小さなことで私にとって意味のある標準的なソースはありますか?

編集:たとえば documentation

-XDataKindsを使用すると、GHCは適切なすべてのデータ型を種類に自動的に昇格させ、その(値)コンストラクターを型コンストラクターに昇格させます。次のタイプ

そして例を与える

data Nat = Ze | Su Nat

次の種類と型コンストラクタを生成します。

Nat :: BOX
Ze :: Nat
Su :: Nat -> Nat

私はポイントを得ていません。 BOXの意味はわかりませんが、ステートメントZe :: NatおよびSu :: Nat -> Natは、ZeとSuがghciで予想されるとおりに通常のデータコンストラクターである場合に、すでに通常何であるかを述べているようです。

Prelude> :t Su
Su :: Nat -> Nat
54
user782220

それでは基本から始めましょう

種類

種類は、たとえば*の種類です

Int :: *
Bool :: *
Maybe :: * -> *

->は、種類レベルでも「関数」を意味するようにオーバーロードされています。そう *は、通常のHaskellタイプの一種です。

GHCiに、:k

データの種類

独自の種類を作成する方法がないため、これはあまり有用ではありません! DataKindsを使用すると、

 data Nat = S Nat | Z

GHCはこれを促進して、対応する種類Natを作成し、

 Prelude> :k S
 S :: Nat -> Nat
 Prelude> :k Z
 Z :: Nat

したがって、DataKindsはkindシステムを拡張可能にします。

用途

GADTを使用してプロトタイプの種類の例をやってみましょう

 data Vec :: Nat -> * where
    Nil  :: Vec Z
    Cons :: Int -> Vec n -> Vec (S n)

これで、Vec型が長さでインデックス付けされていることがわかります。

これが基本的な10kフィートの概要です。

*これは実際に続きます、Values : Types : Kinds : Sorts ...一部の言語(Coq、Agda ..)は、この無限の宇宙のスタックをサポートしていますが、Haskellはすべてを1つの種類にまとめています。

57
jozefg

私の見解は次のとおりです。

次のタイプの長さインデックス付きベクターを考えます。

data Vec n a where
  Vnil  :: Vec Zero a
  Vcons :: a -> Vec n a -> Vec (Succ n) a

data Zero
data Succ a

ここに種類Vec :: * -> * -> *があります。ゼロの長さのInt Vectorを次のように表現できるため、

Vect Zero Int

また、次のような意味のない型を宣言することもできます。

Vect Bool Int

これは、型レベルで型指定のない関数型プログラミングができることを意味します。したがって、データの種類を導入することでこのようなあいまいさを取り除き、そのような種類を持つことができます。

Vec :: Nat -> * -> *

VecNatという名前のDataKindを取得し、次のように宣言できます。

datakind Nat = Zero | Succ Nat

新しいデータの種類を導入することにより、Vecにはより制約のある種類の署名が追加されたため、誰も無意味な型を宣言できません。

39
aycanirican