[解決済み] Haskell型とデータコンストラクタ
質問
私はHaskellを learnyouahaskell.comから学んでいます。 . 私は型コンストラクタとデータコンストラクタを理解するのに苦労しています。たとえば、私はこの違いをよく理解していません。
data Car = Car { company :: String
, model :: String
, year :: Int
} deriving (Show)
とこれを
data Car a b c = Car { company :: a
, model :: b
, year :: c
} deriving (Show)
は単純に1つのコンストラクタを使うだけだと理解しています(
Car
) を使って
Car
. 2番目はよくわかりません。
また、このように定義されたデータ型は、どのように。
data Color = Blue | Green | Red
は、このすべてに適合していますか?
私が理解したところでは、3番目の例(
Color
) は、3つの状態になることができる型です。
Blue
,
Green
または
Red
. しかし、これは私が最初の2つの例を理解する方法と矛盾しています:それは、型
Car
は一つの状態にしかなり得ないということでしょうか。
Car
を構築するために様々なパラメータを取ることができるのでしょうか?もしそうなら、2番目の例はどのように適合するのでしょうか?
本質的に、私は上記の3つのコード例/構造を統一する説明を探しています。
どのように解決するのですか?
で
data
宣言では
型コンストラクタ
は等号の左側にあるものです。その
データコンストラクタ
は等号の右側にあるものです。型が必要な場合はタイプコンストラクタを使用し、値が必要な場合はデータコンストラクタを使用します。
データコンストラクタ
物事を簡単にするために、色を表す型の例から始めましょう。
data Colour = Red | Green | Blue
ここでは、3つのデータコンストラクタを用意しています。
Colour
は型、そして
Green
は型の値を含むコンストラクタです。
Colour
. 同様に
Red
と
Blue
の値を構築するコンストラクタです。
Colour
. しかし、我々はそれをスパイスにすることを想像することができました
data Colour = RGB Int Int Int
まだ、型だけの
Colour
という型があるだけですが
RGB
は値ではありません。これは3つのIntsを取る関数で
を返す
を返す関数です。
RGB
は型を持っています。
RGB :: Int -> Int -> Int -> Colour
RGB
はデータコンストラクタであり、いくつかの
値
を引数として取り、それを使って新しい値を構築する関数です。オブジェクト指向プログラミングをしたことがある人なら、このことを認識できるはずです。オブジェクト指向では、コンストラクタもいくつかの値を引数として取り、新しい値を返します。
この場合、もし
RGB
を適用すると、色の値が得られます。
Prelude> RGB 12 92 27
#0c5c1b
私たちは
値を構築した
型の
Colour
をデータコンストラクタの適用により構築します。データコンストラクタは、変数のように値を含むか、他の値を引数として受け取り、新しい
値
. もしあなたが以前にプログラミングをしたことがあるなら、このコンセプトはそれほど奇妙なものではないはずです。
インターミッション
もし、バイナリツリーを構築して
String
を格納するためにバイナリツリーを構築したい場合、次のようなことを想像してみてください。
data SBTree = Leaf String
| Branch String SBTree SBTree
ここで見るのは、型
SBTree
という型であり、2つのデータコンストラクタを含んでいます。言い換えれば、2つの関数(すなわち
Leaf
と
Branch
の値を構築します)。
SBTree
型の値を構築します。二分木がどのように機能するのかよく知らない人は、そのままお待ちください。バイナリツリーがどのように機能するかは知らなくても大丈夫です。
String
を何らかの形で保存しているということだけです。
また、どちらのデータコンストラクタも
String
引数を取ります。これはツリーに保存される文字列です。
しかし!もし私たちが、この他に
Bool
を格納したい場合は、新しいバイナリツリーを作成する必要があります。それは次のようなものです。
data BBTree = Leaf Bool
| Branch Bool BBTree BBTree
タイプ・コンストラクタ
両方
SBTree
と
BBTree
はタイプ・コンストラクタです。しかし、重大な問題があります。これらがいかに似ているかわかりますか?それは、本当にどこかにパラメータが欲しいというサインです。
だから、こうすればいいんです。
data BTree a = Leaf a
| Branch a (BTree a) (BTree a)
ここで
型変数
a
を型コンストラクタのパラメータとして宣言します。この宣言では
BTree
は関数になっています。これは
型
を引数として取り、新しい
型
.
ここで重要なのは 具体的な型 (例としては
Int
,[Char]
とMaybe Bool
) は、プログラムの中で値を割り当てることができる型であり、また 型コンストラクタ関数 という、値に代入できるように型を与える必要がある関数があります。値は決して "list"型である必要はありません。 である必要があるからです。 とする必要があるからです。同じ精神で、値は決して "バイナリツリー" 型にはなりません。 何か である必要があるからです。
で渡すと、例えば
Bool
を引数として
BTree
という型が返されます。
BTree Bool
を格納する二分木である。
Bool
s. 型変数のすべての出現箇所を置き換える
a
を型
Bool
という型に変換すれば、それがどのように正しいか自分で確認することができます。
もし、あなたが望むなら、表示される
BTree
を関数として
種類
BTree :: * -> *
Kindsはタイプに似ています。
*
は具体的な型を示すので
BTree
は具象型から具象型へということになります。
ラップアップする
ここで一歩下がって、類似点に注意してください。
-
A データコンストラクタ は、0個以上の 値 を受け取り、新しい値を返します。
-
A 型コンストラクタ は、0個以上の 型 を受け取り、新しい型を返します。
パラメータ付きのデータコンストラクタは、値にわずかなバリエーションが欲しい場合に便利です。それらのバリエーションをパラメータに置き、値を作成する人がどの引数を置くかを決定します。同じ意味で、パラメータ付きの型コンストラクタは、型にわずかなバリエーションが欲しい場合に格好のものです! 私たちはそれらのバリエーションをパラメータとして置き、型を作成する人に、彼らがどのような引数を置くかを決定させます。
ケーススタディ
ここでのホームストレッチとしては
Maybe a
型を考えてみましょう。その定義は
data Maybe a = Nothing
| Just a
ここで
Maybe
は具象型を返すタイプ・コンストラクタです。
Just
はデータコンストラクタで、値を返します。
Nothing
は値を含むデータコンストラクタです。の型を見てみると
Just
の型を見ると、次のようになります。
Just :: a -> Maybe a
言い換えると
Just
は
a
型の値を取り、型の
Maybe a
. の種類を見ると
Maybe
の種類を見ると、次のようになります。
Maybe :: * -> *
言い換えると
Maybe
は具象型を取り、具象型を返します。
もう一回! 具象型と型コンストラクタ関数の違いです。のリストを作成することはできません。
Maybe
を実行しようとすると
[] :: [Maybe]
のようにすると、エラーが発生します。しかし
Maybe Int
のリスト、または
Maybe a
. それは
Maybe
は型コンストラクタ関数ですが、リストは具象型の値を含む必要があるからです。
Maybe Int
と
Maybe a
は具象型です(必要であれば、具象型を返す型コンストラクタ関数の呼び出しでもかまいません)。
関連
-
[解決済み] 一般的に `{- |` で始まるHaskellのコメントは何を意味するのですか?
-
[解決済み] 解釈の仕方 (Eq a)
-
[解決済み] Hindley-Milnerのどの部分が理解できないのでしょうか?
-
[解決済み] Project Eulerとの速度比較。CとPythonとErlangとHaskellの比較
-
[解決済み] Haskellで大規模設計?[クローズド]
-
[解決済み] 読んで学ぶべき良いHaskellのソース [終了しました]。
-
[解決済み】代数的なデータ型の代数を悪用する - なぜこれが有効なのか?
-
[解決済み】Haskellの入門編
-
[解決済み] CabalとStackの違いは何ですか?
-
[解決済み] HaskellとF#の主な違いは何ですか?[クローズド]
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラー haskell: スコープ内にありません。どういう意味ですか?
-
[解決済み] Haskell - Ord aの型は何を意味するのでしょうか?
-
[解決済み] Haskell タプルをリスト化する?
-
[解決済み] Haskellにはなぜ "data "と "newtype "があるのですか?重複] [重複] [重複
-
[解決済み] 制約条件付き特殊化
-
[解決済み] なぜ依存型でないのか?
-
[解決済み] Haskellのマルチコアプログラミングはどうなっているのか?
-
[解決済み] Haskellの "Just "構文とは?
-
[解決済み] Haskellの関数合成(.)と関数応用($)イディオム:正しい使い方
-
[解決済み] GHCでコンパイルした小さなHaskellプログラムを巨大なバイナリにする