Clinton
Clinton

Reputation: 23135

Type signature for function containing `runST`

I can write something like this:

import Control.Monad.ST (runST)

x :: (Monad m) => m a
x = undefined

f = runST x

And this will happily compile without a signature for f.

So I've tried something similar:

g :: (Monad m) => m a -> m a
g = undefined

h x = runST (g x)

Yet this doesn't compile without a signature. Which I don't mind too much, as runST is a rank-2 type, but I can't work out what signature to write for h.

(Background)

This is a simplified example of real code I'm writing. Firstly I've got a function that works in MonadRef (e.g. ST or IO). It does a lot of manipulation on vectors. I'm creating a pure wrapper to this, but one needs to pass in the initial mutable vector, and it will produce a pure vector. Unlike the more general first mentioned function, the pure wrapper only works in ST.

Upvotes: 0

Views: 92

Answers (1)

bennofs
bennofs

Reputation: 11963

The type signature that you're looking for is:

{-# LANGUAGE RankNTypes #-}
module Test where

import Control.Monad.ST

g :: (Monad m) => m a -> m a
g = undefined

h :: (forall s. ST s a) -> a
h x = runST (g x)

The (forall s. ST s a) ensures that x cannot decide what s will be and so x has to work for all s, so it cannot leak out STRef or similar out of the ST computation.

Upvotes: 5

Related Questions