Reputation: 1004
For some reason I can't find the answer to this anywhere. I tried Googling "Haskell equal sign arrow" and I'm not getting any results. Let's say we have the following function:
sendMessage :: MonadM e m => Message -> m ()
sendMessage message = do
mClient <- getMessageClient
liftIO $ send mClient message
Where exactly are e and m getting used? Are they being passed into the Message object (function?) and then outputted as a single type, m ()?
I don't think it helps that I'm very new to Haskell, but any help is appreciated here.
Upvotes: 15
Views: 4787
Reputation: 120711
First off: if you want to know what such and such operator does, don't ask StackOverflow, ask Hoogle!
But in fact Hayoo is no use for =>
in particular because, unlike almost everything else in Haskell, this is built-in syntax and not an operator that's defined in some library.
Your signature
sendMessage :: MonadM e m => Message -> m ()
means the following: the type of sendMessage
is Message -> m ()
, where m
can be any monad that has an instance of the MonadM
type class.
That probably doesn't help you much, because in fact MonadM
is a rather involved type class. Better consider a simpler example:
sum :: Num n => [n] -> n
This means: the type of sum is [n] -> n
, where n
can be any number type that's an instance of the Num
class, i.e. the class of types supporting subtraction, multiplication, obviously addition etc.. Actually the syntax is shorthand for
sum :: ∀ n . Num n => [n] -> n
meaning that for all types n
which fulfill the constraint Num n
, the function sum
has the signature [n] -> n
.
You can instantiate such a polymorphic function with any concrete number type: e.g.
sum :: [Int] -> Int
In your example you'd probably instantiate it to something like
sendMessage :: Message -> MessageT IO ()
Upvotes: 15
Reputation: 48581
The type signature
sendMessage :: MonadM e m => Message -> m ()
can be read
Assuming that the constraint
MonadM e m
holds,sendMessage
has typeMessage -> m ()
MonadM
is (almost certainly) a multi-parameter type class with a functional dependency. Its definition probably looks vaguely like
class Monad m => MonadM e m | m -> e where ....
You don't have to worry about that right now. Writing such classes is a somewhat advanced topic. But it expresses that some operations are available that relate the types e
and m
, where the type e
is determined by the type m
.
Upvotes: 3