を検査すると、次kind
のMaybe
ようになります。
λ> :k Maybe
Maybe :: * -> *
さて、Monad
私がこれを得る種類を調べると:
λ> :k Monad
Monad :: (* -> *) -> Constraint
そこには何がConstraint
あり、なぜそれが必要なのですか? なぜこれだけではないの* -> *
ですか?
を検査すると、次kind
のMaybe
ようになります。
λ> :k Maybe
Maybe :: * -> *
さて、Monad
私がこれを得る種類を調べると:
λ> :k Monad
Monad :: (* -> *) -> Constraint
そこには何がConstraint
あり、なぜそれが必要なのですか? なぜこれだけではないの* -> *
ですか?
とは異なりMaybe
、型Monad
ではありません。それは型クラスです。
同じことが他の型クラスにも当てはまります。
Num :: * -> Constraint
Functor :: (* -> *) -> Constraint
Bifunctor :: (* -> * -> *) -> Constraint
where*
は具象型 (Bool
または などInt
) を->
表し、より高次の型 ( などMaybe
) をConstraint
表し、型制約の概念を表します。これが理由です:
私たちが知っているように、次のような署名を作成することはできません:
return :: a -> Monad a -- This is nonsense!
を制約Monad
として使用する必要があるため、「これは機能するモナドでなければならない」と言うには:
return :: (Monad m) => a -> m a
return
これを行うのは、 が古い type では機能しないことがわかっているためです。そのため、さまざまな type の動作を という名前でm
定義しています。つまり、モナドと呼べる単一のものはなく、モナドと呼べる振る舞いだけが存在します。return
Monad
このため、この関数を使用するには何かを Monad として事前に定義しておく必要があるということで、この型制約を作成しました。これが kind がMonad
isである理由です(* -> *) -> Constraint
- それ自体は型ではありません!
Maybe
のインスタンスですMonad
。これは、どこかで誰かが次のように書いていることを意味します。
instance Monad Maybe where
(>>=) = ... -- etc
Maybe
...そして、モナドとしてどのように振る舞うべきかを定義しました。Maybe
これが、前置制約がある関数または型で使用できる理由Monad m => ...
です。これは基本的に、 によって適用される制約を定義する場所Monad
です。
Constraint
は、Show Int
、Monad Maybe
、 などの種類ですMonoid [a]
。=>
大まかに言えば、これはin 型注釈の左側で発生する可能性のあるすべての種類です。
今以来
Show Int :: Constraint
型でInt
あり、つまり
Int :: *
次のように機能的な種類を割り当てることができShow
ます
Show :: * -> Constraint
^-- the result kind
^-- the kind of Int
あなたの場合、たまたま aが のMonad
ような引数を取るMaybe
ので、
Maybe Int :: *
Maybe :: * -> *
Monad :: (* -> *) -> Constraint
^-- the result kind
^-- the kind of Maybe