6

flatMapMonad で複数の(またはHaskell では>>=/bindの) メソッドを定義することは理にかなっていますか? 私が実際に使用するごく少数のモナド ( OptionTryEither射影) は、 flatMap メソッドを 1 つしか定義していません。

たとえば、を生成する関数を取るflatMapメソッドを定義することは理にかなっていますか? たとえば、それは平坦化されますか?(例外を失うことを考えると問題ではありません...)OptionTryOption[Try[User]]Option[User]

それとも、モナドはflatMap同じ種類のモナドを生成する関数を取得して、1 つのメソッドを定義する必要がありますか? この場合、Either射影はモナドではないと思いますか?彼らは?

4

4 に答える 4

5

このことを真剣に考えたことがあります。結局のところ、そのような構成 (すべてのモナド機能を失うことは別として) はあまり興味深いものではありません。内部コンテナーから外部コンテナーへの変換を提供するだけで十分だからです。

joinWith :: (Functor m, Monad m) => (n a -> m a) -> m (n a) -> m a
joinWith i = join . (fmap i)

bindWith :: (Functor m, Monad m) => (n a -> m a) -> m a -> (a -> n a) -> m a
bindWith i x f = joinWith i $ fmap f x

*Main>  let maybeToList = (\x -> case x of Nothing -> []; (Just y) -> [y])
*Main>  bindWith maybeToList [1..9] (\x -> if even x then Just x else Nothing)
[2,4,6,8]
于 2013-05-06T22:25:42.247 に答える
1

「理にかなっている」が何を意味するかによります。

それがモナドの法則と一致していることを意味している場合、その質問が完全に理にかなっているということは私には明確ではありません。具体的な提案を見て伝えなければなりません。あなたが提案したと思う方法でそれを行うと、少なくともいくつかのコーナーケースでは、おそらく構成に違反することになります。

役に立つという意味であれば、確かに、そのようなものが役立つケースはいつでも見つかります。問題は、モナドの法則に違反し始めると、不注意な関数型 (圏論) 推論者のためにコードにトラップを残してしまうことです。モナドのように見えるものを実際にモナドにする方が良いです(一度に1つだけですが、ラを切り替える明示的な方法を提供できます-しかし、Either書かれLeftProjectionRightProjectionいるとおりであり、厳密に言えばモナドではありません)。または、それがどのように見えるかではないことを説明する本当に明確なドキュメントを書きます. さもなければ、誰かが法が成り立つと仮定して陽気に進み、*ピッと*します。

于 2013-05-06T21:31:12.820 に答える
1

私の知る限り、特定のデータ型については意味がありません.1つの定義しか持てませんbind

Haskell では、モナドは次の型クラスです。

instance Monad m where  
    return :: a -> m a
    bind   :: m a -> (a -> m b) -> m b

具体的には、私たちが持っているリストMonadに対して、

instance Monad [] where
    return :: a -> [] a
    (>>=)   :: [] a -> (a -> [] b) -> [] b

次に、モナド関数を考えてみましょう。

actOnList :: a -> [] b 
 ....

説明するユースケース、

$ [1,2,3] >>= actOnList

関数actOnListでは、リストが別の型によるポリモーフィックな型制約であることがわかります (こちら[])。次に、リストモナドのバインド演算子について話すときは、 によって定義されたバインド演算子について話し[] a -> (a -> [] b) -> [] bます。

あなたが達成したいのは、bind次のように定義された演算子です[] Maybe a -> (a -> [] b) -> [] b。これは最初のものの特化バージョンではなく、別の関数であり、型シグネチャに関して、bindあなたが持っているものを返さないので、それがあらゆる種類のモナドの演算子になる可能性があることを本当に疑っています消費されます。関数を使用してあるモナドから別のモナドに移動することは確かですが、この関数はbindリストの演算子の別のバージョンではありません。

これが私が言った理由です、特定のデータ型については意味がありません。私が知る限り、 の定義は 1 つしか持てませんbind

于 2013-05-06T21:55:13.363 に答える