2012-04-20 11 views
13

私はHaskellの新人で、現在Real World Haskellを見ています。本書では、型コンストラクタは型シグネチャでのみ使用され、値コンストラクタは実際のコードで使用されると説明しています。また、両方の名前が互いに独立していることを示す宣言の例を示します。最初の場所に2つのコンストラクタが必要なのはなぜですか?そのうちの1つだけが実際のコードで使用されていますか?実際のコードで型コンストラクタを使用しないので、型コンストラクタはどのような目的を果たしますか?なぜHaskellの型コンストラクタに加えて値コンストラクタがありますか?

+11

「実際のコード」というフレーズは、プログラムで型コンストラクタを使用しないことを意味するため、残念です。作成者が実際に型のコンストラクタが型の注釈にのみ使用されることを意味していたからです。これは、実際のコードでは使用しないため、Cでキーワード "int"や "long"を必要としないということに相当します(実際のコードとしてカウントされない宣言でのみ使用されます) ")。 –

+0

...受け入れませんか? :) –

答えて

22

名前が多分誤解を招くかもしれません。 型のコンストラクタは、宣言する型の名前を表します。それらは、値ではなくタイプを構築するため、実際には型の変数をパラメータ化して型のファミリを定義するため、呼び出されます。彼らはC++のテンプレートやJavaのジェネリックのようなものです。 data MyType a b = Constr a bでは、MyTypeは2つのタイプabを使用して新しいタイプ(MyType a b)を作成するタイプコンストラクタです。

値コンストラクタは、他の(オブジェクト指向の)言語で "コンストラクタ"と呼ばれる唯一の部分です。その型の値を作成するために必要なためです。したがって、前の例では、値コンストラクタConstr :: a -> b -> MyType a bを使用した場合、値Constr "abc" 'd' :: MyType [Char] Charを作成することができます。後者は実行時値でありながら、型と値についての直感を取得する

+2

私は-1を取り除くために私の答えを改善する方法を尋ねてもいいですか?どうしましたか? –

7

一つの便利な方法は、前者がコンパイル時値であるということです。言い換えると、型コンストラクタは、コンパイル時にプログラムをタイプする唯一の目的のために、Haskell型のセットの値のコンストラクタです。つまり、実行時に型を構築することはできず、コンパイル時に値を構築することもできません。

したがって、タイプ値に基づいて実行時に明示的に分岐することはできません(暗黙的にタイプメーターを使用することもできます)ので、タイプコンストラクターは実行時オブジェクトとして全く役に立たず、多くの場合、完全に欠けています最終的なバイナリ。逆に、値コンストラクタは実行時にその型のセットで値を構築することができるため、コンパイル時オブジェクトとしては全く役に立たない。

この単純なプロパティのため、型コンストラクタと値コンストラクタは明白に名前を共有できます。

+0

これは、緊急の背景から来た人々にとって理解しやすい答えです! –

16

「オブジェクトが実際に実行される唯一のものならば、なぜクラスオブジェクトが必要なのですか?

2種類のコンストラクタは異なるジョブを実行します。型コンストラクタは型シグネチャを取ります。値のコンストラクタは実行可能なコードになります。

最も簡単なケースでは、タイプ "コンストラクタ" の型名です。最も単純なケースでは、型には値コンストラクタが1つしかありません。ですから、

data Point = Point Int Int

のようなもので終わるあなたは「今私に一体何が二回Pointを記述する必要がなぜ?」自分自身に言うかもしれません

しかし、今はそれほど簡単な例を考えてみます。

data Tree x = Leaf x | Branch (Tree x) (Tree x)

ここTreeは型コンストラクタです。あなたは型引数を与え、型を "構築"します。したがって、Tree Intは1つのタイプ、Tree Stringは別のタイプなどです。 (C++のテンプレートやJavaやEiffelのジェネリックと同様)

一方、Leafは値コンストラクタです。値を指定すると、1ノードのツリーが作成されます。したがって、Leaf 5Tree Intの値、Leaf "banana"Tree Stringの値です。

Branchの場合も同様です。 2つのツリー値を取り、それらのツリーを子として持つツリーノードを構築します。たとえば、Branch (Leaf 2) (Leaf 7)Tree Intの値です。

+0

詳細な説明をありがとう! –

関連する問題