Reputation: 11262
I'm playing with http://hackage.haskell.org/packages/archive/vault/0.2.0.0/doc/html/Data-Vault-ST.html and want to write functions like the following:
onVault f = runST (f <$> Vault.newKey)
onVault2 f = runST (f <$> Vault.newKey <*> Vault.newKey)
etc. If I replace these functions with ones that take no arguments and call a particular function instead of f, it works, but these higher-order functions will not type check.
What is going on and can I fix it?
Upvotes: 3
Views: 140
Reputation: 139930
You need to give onVault
and onVault2
rank 2 types.
{-# LANGUAGE Rank2Types #-} -- RankNTypes would also work
onVault :: (forall s. Key s a -> b) -> b
onVault2 :: (forall s. Key s a -> Key s b -> c) -> c
This is because runST :: (forall s. ST s a) -> a
requires that the passed action is polymorphic in the state thread parameter s
, which is a type-level trick used to guarantee purity. See the ST monad article on HaskellWiki for details.
Upvotes: 3