I just learned about monads, and I've been trying to implement a lot of the functions in Control.Monad. I just got to ap
, but I can't make it work. I made a function almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
, and I tried to compose it with another function I made, flatten :: Monad m => m (m b) -> m b
. The problem is when I try to use ap = flatten . almostAp
, I get
Occurs check: cannot construct the infinite type: m ~ (->) (m a)
Expected type: m (a -> b) -> m a -> m a -> m b
Actual type: m (a -> b) -> m a -> m (m b)
In the second argument of ‘(.)’, namely ‘almostAp’
In the expression: (flatten . almostAp)`
But, (flatten .)
has type Monad m => (a -> m (m b)) -> a -> m b
according to ghci, so why does this happen?
Here are the function definitions (I know I can clean them up with =<<
and the functor laws):
almostAp :: Monad m => m (a -> b) -> m a -> m (m b)
almostAp = (flip (\x -> fmap ($x))) . (fmap (flip (>>=))) . (fmap (return .))
flatten :: Monad m => m (m a) -> m a
flatten = (>>= id)