If you type :i Monad in ghci, you will see this instance instance Monad ((->) r) What this means is a function where the first argument is of type 'r'... is a monad. You can in fact use do notation / return on a tuple to manipulate its second argument monadically. So let's look at what that does to the type signature of join when 'm' is ((->) b) join :: Monad m => m (m a) -> m a -- m = ((->) b) join :: ((->) b ((->) b a)) -> (((->) b a)) Now we just have to move the arrows from prefix to infix. Let's do it step by step. join :: ((->) b (b -> a)) -> (b -> a) join :: (b -> (b -> a)) -> (b -> a) x -> (y -> z) is equivalent to x -> y -> z join :: (b -> b -> a) -> (b -> a) join :: (b -> b -> a) -> b -> a So now when you put an operator into it that takes two arguments (,) :: a -> b -> (a,b) You get the type you saw. join (,) :: b -> (b, b) On Fri, Dec 8, 2017 at 10:37 AM, Quentin Liu <quentin.liu.0415@gmail.com> wrote:
Hi,
The function `join` flattens a double-layered monad into one layer and its type signature is
join :: (Monad m) => m (m a) -> m a
But when the first argument supplied is `(,)`, the type signature becomes
join (,) :: b -> (b, b)
in ghci. The monad constraint is lost when supplied the first argument. So my question is why the type constraint is lost and what monad is supplied here.
Regards, Qingbo Liu
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners