[Haskellcafe] REALLY simple STRef examples
Simon PeytonJones
simonpj at microsoft.com
Fri Aug 4 18:18:08 EDT 2006
Chad
 x = runST $ return (1::Int)
This code looks simple, but it isn't. Here are the types:
runST :: forall a. (forall s. ST s a) > a
($) :: forall b c. (b>c) > b > c
return 1 :: forall s. ST s Int
To typecheck, we must instantiate
b with (forall s. ST s Int)
c with Int
In HM that's impossible, because you can't instantiate a type variable
(b) with a polytype (forall s. ST s Int). GHC will now let you do that
(a rather recent change), but in this case it's hard to figure out that
it should do so. Equally plausible is to instantiate b with (ST s'
Int), where s' is a unification variable.
One way to make this work is to look at $'s first argument first. Then
it's clear how to instantiate b. Then look at the second argument. But
if you look at the second argument first, matters are much less clear.
GHC uses an algorithm that is insensitive to argument order, so it can't
take advantage of the lefttoright bias of this example.
It's unfortunate that such a simplelooking piece of code actually
embodies a rather tricky typing problem! Of course there is no problem
if you don' use the higher order function $. Use parens instead
x = runST (return 1)
Simon
 Original Message
 From: haskellcafebounces at haskell.org
[mailto:haskellcafebounces at haskell.org] On Behalf Of
 Chad Scherrer
 Sent: 19 July 2006 23:02
 To: haskellcafe at haskell.org
 Subject: [Haskellcafe] REALLY simple STRef examples

 I've looked around at the various STRef examples out there, but still
 nothing I write myself using this will work. I'm trying to figure out
 how the s is escaping in really simple examples like

 x = runST $ return 1

 y = runST $ do {r < newSTRef 1; readSTRef r}

 Neither of these works in ghci  they both say

 <interactive>:1:0:
 Inferred type is less polymorphic than expected
 Quantified type variable `s' escapes
 Expected type: ST s a > b
 Inferred type: (forall s1. ST s1 a) > a
 In the first argument of `($)', namely `runST'
 In the definition of `it':
 ...

 I thought maybe I needed to replace 1 with (1 :: Int) so the state
 representation didn't force the type, but it still gives the same
 result.

 Can someone point me to the simplest possible runST example that
 actually works? Thanks!
More information about the HaskellCafe
mailing list