After studying about monads in Haskell — a subject that is very compelling for everything that implies — I wonder if I could define a monad on my own without using the already defined typeclasses.
Instead of making Monad an instance of Functor, I just want to define a monad per se, with it's own fmap function (Also I wanted to change some function names such as return and call it unit).
A monad may be defined by the bind operator (>>=) and the function return, but it also may be defined in terms of return and join since this last function it can be expressed in terms of the bind operator: join m = m >>= id. So a monad could be (technically) defined in terms of return and join and nothing else. The function fmap is required (and the base of existence of a Functor in Haskell), but also could be defined in terms of return, for it may be defined also (I think) as follows: fmap f m = m >>= return . f (before edit it was written, fmap f m = return . f; it was obviously a typo).
Yet I know this wouldn't be as efficient as using the predefined Monad typeclass, it's just to understand better the Haskell language.
How can I accomplish that? This is a depiction of this concept out of my head, right now, so it's not useful code:
-- Just a sketch
infixr 9 ∘
(∘) :: (b -> c) -> (a -> b) -> a -> c
(∘) g f x = g (f x)
--(f ∘ g) x = f (g x)
-- My own 'fmap'
--mapper id  =  id
--mapper (f ∘ g) = mapper f ∘ mapper g
-- My monad
class MyMonadBase (m :: * -> *) where
    unit :: a -> m a   --return
    join :: m (m a) -> m a
    join = (>>= id)
    mapper f m = m >>= unit ∘ f
--Testing:
data Tree a = Leaf a | Branch (Tree a) (Tree a)
instance MyMonadBase Tree where
    unit = Leaf
    join (Leaf x) = x
    join (Branch l r)  = Branch (join l) (join r)
Am I in the right track (conceptually)?
 
    