Reputation: 41909
Looking at runZMQ
from System.ZMQ4.Monadic:
What is the meaning of this type signature?
λ: :t runZMQ
runZMQ
:: transformers-0.4.2.0:Control.Monad.IO.Class.MonadIO m =>
(forall z. ZMQ z a) -> m a
In particular, I don't understand the forall
.
Upvotes: 3
Views: 86
Reputation: 4464
ErikR's answer is a good one about why there is a forall
but thewhat
is a different matter.
To take a simpler answer, take the type
f :: (a -> a) -> a
This function can be called on any function with the same input and output type. For example f (*2) :: Int
is a well typed term.
On the other hand
f :: (forall a. a -> a) -> Int
Requires that the input function be polymorphic in a
. In other words, it requires that the input function be applicable to any type. Basically this means that it can only be id
or something that returns an error, because otherwise it can't create a value of an arbitrary type.
This limiting behavior is used by systems to enforce certain invariants, for example the ST
ErikR mentions uses it to make sure that internal state can't be accessed externally.
Upvotes: 2
Reputation: 52039
From the ZQM docs:
The ZMQ monad is modeled after ST and encapsulates a Context. It uses the uninstantiated type variable z to distinguish different invoctions of runZMQ and to prevent unintented use of Sockets outside their scope. Cf. the paper of John Launchbury and Simon Peyton Jones Lazy Functional State Threads.
So the z
parameter acts just like the s
parameter in ST s a
.
One explanation of the ST monad from the Haskell Wiki:
https://wiki.haskell.org/Monad/ST
Upvotes: 2