7

Edx Haskell courseMaybeで、Erik Meijerは、失敗した計算に型を使用することはすべきことではないと繰り返し述べています。代わりに、空のリストを使用する必要があります。

私の理解では、Maybe型は良いものであり、それを使用する必要があります。しかし、リストはモデル化できるものすべてをMaybeモデル化できるようです...では、なぜMaybe型が必要なのでしょうか?

4

5 に答える 5

17

ただし、リストはすべてをモデル化できるようです

"and more" は、 を使用する優れた理由Maybeです。リストのコンシューマとして、0、1、または複数の値を処理できる必要があります。の消費者として、Maybeゼロまたは 1 つの値を処理できる必要があるだけです。したがって、複数の値が意味をなさない場合はMaybe、無意味な値を取得しないことを静的に知るために使用する方がはるかに優れています。

于 2014-11-24T10:38:43.290 に答える
8

リストは、任意の数の結果をモデル化できます。一方、は結果を1 つだけモデル化するか、結果をMaybeまったくモデル化しません

次の関数について考えてみましょう。

f1 :: A -> [B]
f2 :: B -> [C]
f3 :: C -> [D]
f4 :: D -> [E]

f1f2f3またはf4返される要素の数は明確ではありません。では、それらを並べるとどうなるでしょうか。

f  :: A -> [E]
f s = f1 s >>= f2 >>= f3 >>= f4

結果にはいくつの要素が含まれている必要がありますか? 1?ゼロ?誤って n^n (n ~ 入力長) 要素のリストを作成したのでしょうか?

ただし、計算で値が 1 つだけ返されるか、値がまったく返されない場合は、適切な型によって必要なすべての情報がすぐに得られます。

f1 :: A -> Maybe B
f2 :: B -> Maybe C
f3 :: C -> Maybe D
f4 :: D -> Maybe E

f  :: A -> Maybe E
f s = f1 s >>= f2 >>= f3 >>= f4

それで、それはそれです。Meijer の声明に戻ります。

Erik Meijer は、失敗した計算に Maybe 型を使用することはすべきではないと繰り返し述べています。代わりに、空のリストを使用する必要があります。

追加の客観的理由がなければ、これは単なる個人的な好みです。fmapよりも優れていることは誰にでも言えますmap。それは私たちがやるべきことです。その時点で、あなたは私を信じるか、質問するかのどちらかです。彼が講義で明らかにしなかった場合は、直接彼に尋ねてください。

于 2014-11-24T10:49:27.303 に答える
1

私はここで合唱団に参加し、彼の議論の詳細をすべて提示されない限り、Meijer の推薦を評価することはできないと言いたい. 私には簡単に思えます:

  1. Maybe0 または 1 の結果を返す関数に使用します。
  2. []0 個以上の結果を返す関数に使用します。
  3. 異なる選択を行う関数を組み合わせて一致させる必要がある場合、1 つのオプションは、関数のような関数listToMaybe :: [a] -> Maybe amaybeToList :: Maybe a -> [a]fromData.Maybeを使用して、あるスタイルで記述された関数を別のスタイルで機能するように適合させることです。
  4. Maybeまたはを使用するかどうかの選択を遅らせたい場合は、またはクラス[]を使用できます。AlternativeMonadPlus

ポイント 4 の例:

import Control.Applicative (pure, Alternative(..))

safeDiv :: (Alternative f, Fractional a, Eq a) => a -> a -> f a
safeDiv _ 0 = empty
safeDiv x y = pure (x / y)

{-

>>> safeDiv 5 2 :: Maybe Float
Just 2.5

>>> safeDiv 5 0 :: Maybe Float
Nothing

>>> safeDiv 5 2 :: [Float]
[2.5]

>>> safeDiv 5 0 :: [Float]
[]

-}

bothSqrt :: (Alternative f, Floating a) => a -> f a
bothSqrt x = let x' = sqrt x
             in pure x' <|> pure (-x')

{-

>>> bothSqrt 5 :: Maybe Float
Just 2.236068

>>> bothSqrt 5 :: [Float]
[2.236068,-2.236068]

>>> bothSqrt 5 >>= flip safeDiv 2 :: Maybe Float
Just 1.118034

>>>> bothSqrt 5 >>= flip safeDiv 2 :: [Float]
[1.118034,-1.118034]

-}
于 2014-11-26T02:10:26.430 に答える