I am currently 'getting my feet wet with monads' (http://learnyouahaskell.com/a-fistful-of-monads#getting-our-feet-wet-with-maybe) and still struggling with part of this concept. I understand the maybe monad mentioned there and can see how to call it, as mentioned here:
ghci> return "WHAT" :: Maybe String
Just "WHAT"
ghci> Just 9 >>= \x -> return (x*10)
Just 90
ghci> Nothing >>= \x -> return (x*10)
Nothing
How do I however call my own monad instance rather than the maybe one if I declare my own instance with its own type, like so:
newtype CustomM a = CustomM {runCustomM:: a -> String}
instance Monad CustomM where
return a = CustomM (\a -> mempty)
m >>= f = CustomM (\a -> mempty)
instance Functor CustomM where
fmap = liftM
instance Applicative CustomM where
pure = return; (<*>) = ap
using the return
will just call the Maybe Monad
I suspect. And what about the >>=
it would require me to give it a certain type.
NB. I have only made the bind the same way as the return, because I still struggle with understanding what it is supposed to return, and how I can give it a monad m
and call the function f on it's value a
, when I don't specify the packed type more thoroughly in the left side. But I shall make another post about that.
You can create a value of your CustomM
type just like you did with Maybe
, using return
:
cm = return "WHAT" :: CustomM String
You can also run it, after a fashion:
Prelude Control.Monad> runCustomM cm "foo"
""
Clearly, though, since you've hard-coded it to return mempty
, it returns the mempty
value for String
, which is ""
.
All that said, though, a -> String
is contravariant in a
, so it can't be a useful Functor
instance. And since it can't be a useful Functor
instance, it also can't be a useful Monad
instance.
While you can define a degenerate implementation as in the OP, you're not going to have much success making CustomM
do anything for real.
Try, instead, swapping the types like e.g. String -> a
.