Kevin Meredith
Kevin Meredith

Reputation: 41909

Understanding `System.ZMQ4.Monadic`'s `forall` in Signature

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

Answers (2)

k_g
k_g

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

ErikR
ErikR

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

Related Questions