こんにちは私はHaskellのParameterizedTypesトピックを自分で学んでいる間、些細なことですが疲れ果てた質問があります。これが私の質問です:
これがの定義であるように見えますMaybe
:
data Maybe a = Just a | Nothing
そして、私たちはこれを次のように使用します:
Just "hello world"
Just 100
しかし、なぜ型変数を取ることができないのですか?
例えば:
Just String
Just Int
私はこの問題がかなりばかであることを知っています、しかし私はまだそれを理解することができません...
まず、String
とInt
は型変数ではなく型(必要に応じて型定数)であることに注意してください。しかし、それはあなたの質問の目的にとっては実際には重要ではありません。
重要なのは、Haskells型言語と値言語の違いです。これらは一般的に離れて保たれます。String
andInt
とMaybe
は型言語で生活し、"hello world"
and100
とJust
とNothing
は価値言語で生活します。それぞれが反対側について何も知りません。コンパイラは「値のこの記述がその型に属する」ことを知っているだけですが、実際には型はコンパイル時にのみ存在し、値は実行時にのみ存在します。
少し紛らわしい2つのこと:
タイプ言語と値言語の両方に存在する名前を持つことができます。最もよく知られているのは()
、次のような単なる同義語タイプです。
newtype Endo a = Endo { runEndo :: a -> a }
しかし実際には、これらは2つの別個のエンティティです。型コンストラクターEndo :: *->*
(これらについては以下を参照*
)と値コンストラクターEndo :: (a->a) -> Endo a
です。それらはたまたま同じ名前を共有していますが、スコープが完全に異なります。addTwo x = x + 2
との両方を宣言する場合と同様にgreet x = "Hello "++x
、x
シンボルの両方の使用は互いに関係がありません。
data
構文は、交絡型と値に思えます。それ以外の場所では、タイプと値は常に、で区切る必要があります::
。最も一般的なのは署名です。
"hello world" :: String
100 :: Int
Just :: Int -> Maybe Int
{-hence-}Just 100 :: Maybe Int
Nothing :: Maybe Int
foo :: (Num a, Ord a) => a -> Maybe a -- this really means `forall a . (Num a, Ord a) => a -> Maybe a
foo n | n <= 0 = Nothing
| otherwise = Just $ n - 1
実際、data
次の機能を有効にすると、その構文を使用して、より特徴的な方法で定義することもできます-XGADTs
。
data Maybe a where
Just :: a -> Maybe a
Nothing :: Maybe a
ここ::
でも、値レベル(左)とタイプレベルを明確に区別しています。
あなたは実際にそれをもう1つのレベルに上げることができます:上記の宣言はまた書くことができます
data Maybe :: * -> * where
Just :: a -> Maybe a
Nothing :: Maybe a
ここMaybe :: * -> *
の手段、「Maybe
持っているタイプレベルのものであるようなもの * -> *
」、すなわち、それは一種のタイプレベルの引数を取ります*
(などInt
)や種類別のタイプのレベルのものを返します*
(ここでは、Maybe Int
)。タイプが値に対してであるように、種類はタイプに対してです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加