2016-11-27 8 views
0

チュートリアルFunctors, Applicatives, And Monads In PicturesとそのJavaScript versionに従っている間に私の質問が出てきました。Monad "unboxing"

ファンクタがコンテキストから値をアンラップするとのテキストが表示された場合、私はJust 5 - >5変換が行われていることを理解しています。 What does the "Just" syntax mean in Haskell?に従って、ちょうどMaybeモナドの「範囲で定義されています」。

私の質問はアンラッピングしているもの全体について非常に魔法的ですか?つまり、スコープされた変数を自動的にアンラップする言語ルールを持つ問題は何ですか?このアクションは、シンボルJust 5が整数5に対応するテーブルのようなものでの検索に過ぎないと私は思っています。

私の質問は、Just 5がプロトタイプの配列インスタンスであるJavaScriptバージョンからインスピレーションを受けています。だからアンラップは、まさにロケット科学ではありません。

これは「計算のための」タイプの理由なのか、「プログラマー向けの」ものなのでしょうか?プログラミング言語レベルでJust 55を区別する理由は何ですか?

答えて

7

まず、私はあなたがモナドを理解することができるとは思わないタイプの値からタイプaの値をdistinguighする方法と、(Haskellのような言語を習得することなく、すなわち)型システムのようなHaskellのを理解せずようなものです。はい、そうでないと主張するチュートリアルはたくさんありますが、ハスケルを学ぶ前にそれらの多くを読んだことがありませんでした。だから私のアドバイス:もしあなたがモナドを理解したいなら、ハスケルを少なくともいくつか学んでください。あなたの質問に

は、「なぜ、プログラミング言語レベルで5からJust 5を区別するのですか?」。型安全のため。 Haskellでないことが起こるほとんどの言語では、nullnilwhateverは、値が存在しないことを表すためによく使われます。しかし、これはしばしば、NullPointerExceptionsのようなものになります。値が存在しないことが予想されなかったからです。

ハスケルでは、nullはありません。したがって、タイプがInt、またはそれ以外の値の場合、その値はnullにはなりません。あなたは価値があることが保証されています。すばらしいです!しかし時には値の欠如をエンコードすることを実際にしたい/必要とすることがあります。ハスケルでは、それにはMaybeを使用しています。だからタイプMaybe Intの何かはJust 5またはNothingのようなものです。この方法では、明示的に値が存在しない可能性があり、明示的に値をアンラップする必要があるため、誤ってNothingである可能性があることを忘れることはできません。

MaybeはMonad型クラス(Javaに精通していればJavaクラスのようなビットです)を実装している点を除けば、Monadsとはまったく関係ありません。つまり、主にモナドではないかもしれませんが、ちょうどモナドでもあります。

2

「アンラップ」とは、コンテナによって異なります。 Maybeは一例にすぎません。コンテナがMaybeの代わりに[]の場合、「アンラッピング」は全く異なるものを意味します。

アンラッピングしているもの全体についての魔法は、抽象化です。モナドでは、コンテナの性質を抽象化する「アンラッピング」という概念があります。同じように、データ宣言で定義Haskellではデータ型コンストラクタは何もありません:

data Maybe a = Just a | Nothing 

Justはの値を取り、それが

あなたは Justが何を意味するのか尋ねる...「魔法」を取得するために開始しますタイプ Maybe aの値を作成します。これは、Haskellのすべての Maybe a

4

可能な例は、次のとおりです。ハスケルタイプMaybe (Maybe Int)を考えてください。その値は、我々は最初の二つを区別することができませんでしたJustラッパーなしでいくつかの整数n

ため

  • Just Nothing
  • Just (Just n)
  • Nothing
    • 次の形式のものとすることができます。

      実際、オプションタイプMaybe aの全ポイントは、既存のタイプaに新しい値(Nothing)を追加することです。そのようなNothingが確かに新しい値であることを確認するために、Justの中に他の値をラップします。

      タイプ推論の際にも役立ちます。関数呼び出しf 'a'を見ると、タイプCharfが呼び出され、タイプがMaybe CharまたはMaybe (Maybe Char)ではないことがわかります。 typeclassシステムは、fがこれらのケースのそれぞれで異なるインプリメンテーションを持つことを可能にします(これは、いくつかのOOP言語では「オーバーロード」に似ています)。

    5

    あなたは間違った方向からこれを見ていると思います。 Monadは、アンラッピングについて明示的にではなく、です。 Monadは組成についてです。

    タイプの値を得るためにタイプa -> m bの関数を(のタイプ)の値と組み合わせる(必ずしも適用する必要はない)ことができます。わかりやすい方法は、タイプm aの値をタイプaにアンラッピングすることです。しかし、ごくわずかな例がMonadインスタンスで動作します。実際、そのように機能するのはIdentityタイプに相当するものだけです。 Monadのほぼすべてのインスタンスに対して、値をラップすることはできません。

    Maybeを考えてください。開始値がNothingの場合は、タイプMaybe aの値をaの値にアンラッピングすることはできません。モナドの構成は、単なるアンラッピングよりも面白いことをしなければなりません。

    []を考えてください。入力がちょうど長さ1のリストでなければ、タイプ[a]の値をタイプaの値にアンラッピングすることは不可能です。それ以外の場合、モナド合成はアンラッピングよりも面白いことをしています。

    IOを考えてください。 getLine :: IO Stringのような値には、Stringの値は含まれません。何かをラッピングしていないので、展開することは不可能です。 IOのMonadicの値は何も展開しません。それはより複雑なIO値にIOの値を組み合わせます。

    あなたの視点を調整することは意味があると思います。Monadそれがアンラッピングしているインターフェースだけだったなら、それはかなり役に立たないでしょう。しかし、もっと微妙です。これは合成インターフェースです。

    1

    まず、質問からモナドを削除する必要があります。彼らはこれをすることは何もない。この記事をモナドの視点の1つとして扱ってください。多分それがあなたに合っていないかもしれません。タイプシステムでは、haskellのモナドを理解することはまだほとんど分かりません。

    あなたの質問は次のように言い換えることができます:なぜ暗黙の変換Just 5 => 5がないのですか?しかし、答えは非常に簡単です。値Just 5はタイプMaybe Integerなので、この値はNothingになる可能性がありますが、この場合はコンパイラは何を行う必要がありますか?この状況を解決できるのはプログラマだけです。

    しかし、もっと不快な質問があります。タイプは、たとえばnewtype Identity a = Identity aです。それはちょうどいくつかの価値のラッパーです。なぜ暗黙の変換がないのですかIdentity a => a

    単純な答えは、これを実現しようとすると、現在のシステムには多くの優れた品質を持たないシステムの種類が異なることになります。これによれば、他の可能性のために犠牲にすることができます。

    2

    私の質問は、アンラッピングしているもの全体について非常に魔法ですか?

    魔法はありません。あなたは...定義する(case表現の形でここに)Maybeためfmapよりもまったく同じです

    mapMaybe :: (a -> b) -> Maybe a -> Maybe b 
    mapMaybe f mx = case mx of 
        Just x -> Just (f x) 
        _ -> mx 
    

    を...ありふれたパターンマッチングを使用することができます。 Functorクラスが追加する唯一のものは、間違いなく、非常に便利なことです。マッピングできるさまざまな構造をカバーする抽象レベルです。

    プログラミング言語レベルでJust 55を区別する理由を教えてください。

    Just 55の区別は、それらタイプ間の1つである以上に意味のある - 例えばMaybe IntIntの間です。 x :: Intをお持ちの場合は、はIntの値でご利用いただけます。しかし、mx :: Maybe Intがある場合、Intが欠けている可能性があります(つまり、mxNothingとなる可能性があります)。このタイプのシステムでは、この可能性を認識して処理する必要があります。

    参照:(必ずしもFunctorMonadとしてクラスに関連付けられていない)Maybeの有用性に関するさらなるコメントjpath's answerFunctorおよびMonadMaybeの例を超える)のようなクラスの有用性についてのさらなるコメントについては、Carl's answerを参照してください。