(>>=) :: Monad m => m a -> (a -> m b) -> m b
Why does the function need to be (a -> m b)? Why functions the preserve che inner data type (a -> m a) are not allowed?
You seem to have missed a basic principle behind type variables: you are allowed to instantiate type variables however you please with concrete types, provided they satisfy the typeclass constraints (here, whatever you choose for m must be a Monad) and are all correctly kinded (m must have kind * -> * and a and b must have kind *).
So if you wanted to instantiate (>>=), some possible choices are:
* (>>=) :: Monad m => m a -> (a -> m b) -> m b
* (>>=) :: [a] -> (a -> [b]) -> [b] (instantiating m to [])
* (>>=) :: Monad m => m a -> (a -> m a) -> m a (instantiating b to a)
* (>>=) :: Monad m => m b -> (b -> m b) -> m b (instantiating b to a... this is an equal type to the last one).
* (>>=) :: Maybe Int -> (Int -> Maybe Int) -> Maybe Int
* (>>=) :: Maybe Char -> (Char -> Maybe Int) -> Maybe Int
One last tidbit that can help understand the "shape" of the types for monad combinators. Look for types of the form a -> m b where m is a monad. These are called Kleisi arrows. If you were fanciful, you might imagine a different syntax for them, like a ~> b meaning "a function from a to b with side effects allowed by some monad m".
Looking at the type of bind, you see a raw m a type at the front. This is essentially the same as () -> m a: a function which takes "no inputs", and produces an a with side effects in m. 904
The m b at the end is similar.
If we rewrite this type in terms of these <PERSON><IP_ADDRESS> Monad m => m a -> (a -> m b) -> m b
Why does the function need to be (a -> m b)? Why functions the preserve che inner data type (a -> m a) are not allowed?
You seem to have missed a basic principle behind type variables: you are allowed to instantiate type variables however you please with concrete types, provided they satisfy the typeclass constraints (here, whatever you choose for m must be a Monad) and are all correctly kinded (m must have kind * -> * and a and b must have kind *).
So if you wanted to instantiate (>>=), some possible choices are:
* (>>=) <IP_ADDRESS> Monad m => m a -> (a -> m b) -> m b
* (>>=) <IP_ADDRESS> [a] -> (a -> [b]) -> [b] (instantiating m to [])
* (>>=) <IP_ADDRESS> Monad m => m a -> (a -> m a) -> m a (instantiating b to a)
* (>>=) <IP_ADDRESS> Monad m => m b -> (b -> m b) -> m b (instantiating b to a... this is an equal type to the last one).
* (>>=) <IP_ADDRESS> Maybe Int -> (Int -> Maybe Int) -> Maybe Int
* (>>=) <IP_ADDRESS> Maybe Char -> (Char -> Maybe Int) -> Maybe Int
One last tidbit that can help understand the "shape" of the types for monad combinators. Look for types of the form a -> m b where m is a monad. These are called Kleisi arrows. If you were fanciful, you might imagine a different syntax for them, like a ~> b meaning "a function from a to b with side effects allowed by some monad m".
Looking at the type of bind, you see a raw m a type at the front. This is essentially the same as () -> m a: a function which takes "no inputs", and produces an a with side effects in m. The m b at the end is similar. 904