これは実際には、たまたまPreludeで定義されている通常のデータコンストラクターに過ぎません。これは、すべてのモジュールに自動的にインポートされる標準ライブラリです。
多分、構造的に
定義は次のようになります。
data Maybe a = Just a
| Nothing
その宣言は、型Maybe a
変数によってパラメーター化される型を定義しますa
。これは、の代わりに任意の型で使用できることを意味しますa
。
構築と破壊
型には2つのコンストラクターとがJust a
ありNothing
ます。型に複数のコンストラクターがある場合、それは型の値が可能なコンストラクターの1つだけで構成されていなければならないことを意味します。このタイプの場合、値はJust
またはを介して構築されNothing
、他の(エラーではない)可能性はありません。
Nothing
パラメータ型がないため、コンストラクタとして使用される場合Maybe a
、すべての型の型のメンバーである定数値を指定しますa
。ただし、Just
コンストラクターには型パラメーターがあります。つまり、コンストラクターとして使用すると、型a
からへの関数のように機能しますMaybe a
。つまり、型がa -> Maybe a
したがって、型のコンストラクターはその型の値を作成します。もう一方は、その値を使用したい場合であり、パターンマッチングが重要な役割を果たします。関数とは異なり、コンストラクターはパターンバインディング式で使用できます。これは、複数のコンストラクターを持つ型に属する値のケース分析を行うことができる方法です。
Maybe a
パターンマッチで値を使用するには、次のように、コンストラクタごとにパターンを指定する必要があります。
case maybeVal of
Nothing -> "There is nothing!"
Just val -> "There is a value, and it is " ++ (show val)
その場合の式では、最初のパターンは値がの場合に一致Nothing
し、2番目のパターンは値がで構成された場合に一致しJust
ます。2番目のものも一致する場合は、一致する値が作成されたときにコンストラクターにval
渡されたパラメーターに名前もバインドしJust
ます。
たぶん意味
たぶん、あなたはすでにこれがどのように機能するかを知っていました。実際にはMaybe
値に魔法はありません。それは通常のHaskell Algebraic Data Type(ADT)にすぎません。ただしInteger
、例からなど、型を効果的に「リフト」または拡張して、値Nothing
の欠如を表す追加の値()を持つ新しいコンテキストに拡張するため、かなり使用されています!型システムではInteger
、そこにある可能性のある値に到達する前に、その追加の値を確認する必要があります。これにより、驚くべき数のバグが防止されます。
今日、多くの言語がこのような「値なし」の値をNULL参照で処理しています。著名なコンピュータサイエンティストであるトニーホアレ(彼はQuicksortを発明し、チューリングアワードの受賞者です)は、これを彼の「10億ドルの間違い」として所有しています。Maybeタイプはこれを修正する唯一の方法ではありませんが、効果的な方法であることが証明されています。
たぶんファンクターとして
ある型を別の型に変換して、古い型の操作も新しい型で機能するように変換できるという考え方は、という便利なインスタンスFunctor
をMaybe a
持つHaskell型クラスの背後にある概念です。
Functor
はと呼ばれるメソッドを提供fmap
します。これは、基本型(などInteger
)の値に及ぶ関数を、リフト型(などMaybe Integer
)の値に及ぶ関数にマッピングします。値を処理fmap
するために変換された関数は、次のように機能しますMaybe
。
case maybeVal of
Nothing -> Nothing -- there is nothing, so just return Nothing
Just val -> Just (f val) -- there is a value, so apply the function to it
したがって、Maybe Integer
値m_x
とInt -> Int
関数がある場合、実際に値を取得するかどうかを心配することなく、関数をに直接適用f
できます。実際、リフトされた関数のチェーン全体を値に適用でき、終了時に明示的に1回だけチェックすることを心配するだけで済みます。fmap f m_x
f
Maybe Integer
Integer -> Integer
Maybe Integer
Nothing
たぶんモナドとして
の概念にMonad
まだ慣れているかはわかりませんが、少なくともIO a
以前に使用したことがあり、型シグネチャIO a
はと非常によく似ていMaybe a
ます。けれどもIO
、それはあなたにそのコンストラクタを公開していないので、唯一のHaskellのランタイムシステムによって、「走る」ことができるという点で特別で、それもまだだFunctor
ことに加えてMonad
。実際、a Monad
はFunctor
いくつかの追加機能を備えた特別な種類であるという重要な意味がありますが、これはそのための場所ではありません。
とにかく、のようなモナドIO
「値の計算その結果」を表す新しいタイプのマップタイプと、あなたはに機能を持ち上げることができるMonad
非常に介して、タイプfmap
と呼ばれる様機能 liftM
値の結果が評価したことを「計算になり、通常の関数であること関数。"
その(あなたがこれまでのところを読んでいる場合)あなたはおそらく推測しているMaybe
にもありますMonad
。「値を返せない可能性のある計算」を表します。fmap
例と同様に、これにより、各ステップの後にエラーを明示的にチェックする必要なく、一連の計算を行うことができます。そして実際、Monad
インスタンスの構築方法では、に遭遇するとすぐにMaybe
値の計算が停止するNothing
ため、計算の途中での即時の中止や値のない戻りのようなものです。
あなたは多分書いたかもしれない
前に言ったようにMaybe
、言語構文やランタイムシステムに組み込まれている型には固有のものはありません。Haskellがデフォルトで提供していない場合は、自分ですべての機能を提供できます。実際、とにかく自分でもう一度名前を変えて書いて、同じ機能を得ることができます。
うまくいけば、Maybe
タイプとそのコンストラクターを理解できたと思いますが、それでも不明な点がある場合は、お知らせください!
Maybe
は他の言語が使用する場所null
やnil
(いたるところにひどい言葉がNullPointerException
潜んでいる)場所をよく使用することを述べておく必要があります。現在、他の言語もこの構造を使用し始めています。ScalaasOption
、さらにはJava 8でもOptional
型が使用されます。