2016-07-10 15 views
3

でリターンを使用すると、これは>>=のタイプです:Haskellのバインド演算子(>> =)

(>>=) :: Monad m => m a -> (a -> m b) -> m b 

それは2番目の引数としての機能を必要とします。

そして、ここではreturnのタイプです:

return :: Monad m => a -> m a 

戻りm a

そして、これは明らかにチェックを入力します。

(>>) :: Monad m => m a -> m b -> m b 
x >> y = x >>= (\_ -> y) 

をしかし、なぜ次の型チェックを行い、と同様に機能します上記のコード?ここでreturn y

(>>) :: Monad m => m a -> m b -> m b 
x >> y = x >>= return y 

はタイプm aでもないa -> m aことになっています。ではなぜそれは機能しますか?

+0

関数の 'return'は' const'です – Bergi

答えて

5

あなたは実際には2つの異なるモナドをここで混合しています。それは起こっていることです。 x >>= return yreturnMonad (a->)インスタンスで実装されて

(>>) :: ∀ m a b . Monad m => m a -> m b -> m b 
x >> y = x >>= (return :: m b -> a -> m b) y 
     -- aka return :: (m b) -> (a->) (m b) 

に統一このケースである:それはMonad mインスタンスとは何の関係もありません

instance Monad (->) a where 
    return x = \_ -> x 
    ... 

。このreturnが関数モナドで動作する理由については

:コンパイラはこれまでに型クラスのインスタンスについての理由を開始する前にreturn :: m b -> a -> m bが環境から推測されます。現在、タイプm b -> a -> m b、すなわちm b -> (a->m b)は、mb -> ambという形式です。したがって、署名return :: Monad μ => α -> μ αは、コンパイラをμ α ~ amb ~ a->m bに一致させます。この時点でコンパイラは実際にreturnのモナドインスタンスを選択し、a -> m bμ αの形式であり、μ ~ (a->)α ~ m bの形式であることを確認することによってコンパイラは実際にモナドインスタンスを選択します。したがって、(a->)モナドでなければなりません。

+0

ありがとう、私は 'Monad( - >)a'インスタンスを使用しているのでtypechecksの理由を理解していると思います。私がまだ理解していないのは、どのようにして 'Monad( - >)a 'を選んだのでしょうか?その背後にある論理は何でしたか?文字通り 'return'が型チェックを行う唯一のインスタンスであったということでしたか? –

4

関数用のモナドインスタンスがあり、returnreturn x = \_ -> x(または同等にはreturn = const)です。

したがって、関数が期待されるreturn yを実行すると、単純に関数monadのreturnが選択されます。