2017-03-02 12 views
11

私はMaybeとモナドのどちらの型でも演奏していました(連鎖、戻り値による条件付き関数の適用、連鎖関数が失敗したエラーメッセージの返送など)。だから私はモナドを使って同じことを達成することができるように思えます。だから私の質問は、それらの間の実用的または概念的な違いはどこですか?なぜモナドでモナドが必要なのでしょうか

+0

私は騙されていません。素晴らしい質問。 –

答えて

10

もちろん、Maybe aEither Unit aに同形です。事は、彼らは多くの場合、意味的に異なるものを表すために使用されていることである、NoSuchElementExceptionnullを返すと投げの違いのようなビット:

  • Nothing/Noneは「期待」しながら、何かの欠落
  • Left eを表し、何らかの理由でそれを得る際のエラーを示します。

    我々は欠損値(DB NULL)の可能性との接続に問題、DBMSの両方を発現
    query :: Either DBError (Maybe String) 
    

    :私たちも何かに2を組み合わせたかもしれない、と述べた

、または何でも(より良いデザインはないと言っているわけではありませんが、あなたはその点を知っています)。

境界が流動的な場合もあります。 saveHead :: [a] -> Maybe aの場合、エラーの予想される可能性が関数の目的でコード化されていると言えるかもしれませんが、saveDivideFloat -> Float -> Either FPError FloatまたはFloat -> Float -> Maybe Floatとしてエンコードされているかもしれません(やはりちょっとした愚かな例...) 。

疑いで、最良のオプションは、(data QueryResult = Success String | Null | Failure DBErrorのような)セマンティックエンコードでカスタム結果ADTを使用すると、それは「伝統的期待」される単純な例にMaybeを好むように思われる場合(ただしだろう主観ポイント、あなたが経験を積んだら大丈夫です)。

5

@phgの回答は素晴らしいです。私はそれらを学んでいたとき、私は私のためにそれを明確にアップ助けた何かでチャイムます:

  • Maybeは1(値)またはnoneである - つまり、あなたが値を持っているか、あなたは何もありません
  • Eitherです論理的な分離にはなりますが、常に1つ以上の値があります。つまり、またはがありますが、両方はありません。

Maybeは、値がある場合とない場合(たとえば、リスト内の項目を検索する場合など)に最適です。リストには、それが含まれている場合、我々はそうでない場合、我々はNothing

Eitherは、あなたのコード内のブランチの完璧な表現であり得る(Maybe x)を取得する - 一つの方法または他に行くために起こっています。 LeftまたはRight。私たちはそれを覚えてニーモニックを使用します:Rightです。正しい)です。 Leftが間違っていますウェイ(エラー)です。これはそれが唯一の使用ではありませんが、間違いなく最も一般的です。

最初は微妙な違いがあるかもしれませんが、実際には非常に異なるものに適しています。

+1

論理的論理和について言及するには、+ 1が得られます。これは、FPを初めて使う人にとっては、*非常に*近づける答えです。 –

+0

Thanks Jared。あなたのフィードバックは私にはたくさんのことを意味します^ _ ^ – naomik

1

これは、すべての商品タイプをで2タプルとすべての非再帰的な合計タイプで表すことができるということで、これを極端に説明することができます。さらに再帰型を表現するには、固定小数点型が必要です。

たとえば、(a, (b, (c,d)))または(((a,b), c), d)と書くことができるときには、4タプル(a,b,c,d)を使用するのはなぜですか?

また、次のような場合にもリストが表示されるのはなぜですか?

data Y f = Y (f (Y f)) 

type List a = Y ((,) (Either() a)) 


nil = Y (Left(), undefined) 

cons a as = Y (Right a, as) 

infixr 4 cons 

numbers = 1 `cons` 2 `cons` 3 `cons` nil 

-- this is like foldl 

reduce f z (Y (Left(), _)) = z 
reduce f z (Y (Right x, xs)) = reduce f (f z x) xs 


total = reduce (+) 0 numbers 
関連する問題