ContT and ST stack

Dear list, I have the following (simplified) piece of code: find :: Int -> [Int] find i = runST . (`runContT` return) $ callCC $ \escape -> do return [] which used to compile correctly under GHC 6.12.3. Now that I've switched to 7.0.2 it gets rejected with the following error: Couldn't match expected type `forall s. ST s c0' with actual type `m0 r0' Expected type: ContT r0 m0 a0 -> forall s. ST s c0 Actual type: ContT r0 m0 a0 -> m0 r0 In the second argument of `(.)', namely `(`runContT` return)' In the expression: runST . (`runContT` return) I'm a little bit lost at what exactly is the problem. Anyone can suggest a solution? Thanks! AB

On Thursday 10 March 2011 14:18:24, Anakim Border wrote:
Dear list,
I have the following (simplified) piece of code:
find :: Int -> [Int] find i = runST . (`runContT` return) $ callCC $ \escape -> do return []
which used to compile correctly under GHC 6.12.3.
Now that I've switched to 7.0.2 it gets rejected with the following error:
Couldn't match expected type `forall s. ST s c0' with actual type `m0 r0' Expected type: ContT r0 m0 a0 -> forall s. ST s c0 Actual type: ContT r0 m0 a0 -> m0 r0 In the second argument of `(.)', namely `(`runContT` return)' In the expression: runST . (`runContT` return)
I'm a little bit lost at what exactly is the problem.
If memory serves correctly, it's impredicative polymorphism. The type of (.), (b -> c) -> (a -> b) -> a -> c, can't handle (x -> forall s. ST s [Int]) Previously there was an implementation of impredicative polymorphism which allowed GHC to handle that construct, but that has been removed (because it was unsatisfactory), so GHC 7 doesn't compile that anymore.
Anyone can suggest a solution?
Parentheses. find i = runST ((`runContT` return) $ callCC $ \escape -> do return [])
Thanks!
AB

On 10 March 2011 14:47, Daniel Fischer
If memory serves correctly, it's impredicative polymorphism.
Indeed. For example the following also doesn't type check in GHC-7: foo :: (forall s. ST s a) -> a foo st = ($) runST st Surprisingly the following does: foo :: (forall s. ST s a) -> a foo st = runST $ st Because GHC contains a special rule for infix $. Also see: http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/19152 Bas

On Thursday 10 March 2011 17:15:29, Bas van Dijk wrote:
On 10 March 2011 14:47, Daniel Fischer
wrote: If memory serves correctly, it's impredicative polymorphism.
Indeed. For example the following also doesn't type check in GHC-7:
foo :: (forall s. ST s a) -> a foo st = ($) runST st
Surprisingly the following does:
foo :: (forall s. ST s a) -> a foo st = runST $ st
Because GHC contains a special rule for infix $. Also see:
http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/19152
Bas
Bedankt. I sort of knew there was a special case for ($) because runST $ do ... works, but not exactly what was handled. So until I forget, I now know it's infix ($) and only that. Cheers, Daniel

Why has the operator (.) troubles with a type like (forall s. ST s a)?
Why can't it match the type 'b' in (.) definition?
2011/3/10 Daniel Fischer
On Thursday 10 March 2011 14:18:24, Anakim Border wrote:
Dear list,
I have the following (simplified) piece of code:
find :: Int -> [Int] find i = runST . (`runContT` return) $ callCC $ \escape -> do return []
which used to compile correctly under GHC 6.12.3.
Now that I've switched to 7.0.2 it gets rejected with the following error:
Couldn't match expected type `forall s. ST s c0' with actual type `m0 r0' Expected type: ContT r0 m0 a0 -> forall s. ST s c0 Actual type: ContT r0 m0 a0 -> m0 r0 In the second argument of `(.)', namely `(`runContT` return)' In the expression: runST . (`runContT` return)
I'm a little bit lost at what exactly is the problem.
If memory serves correctly, it's impredicative polymorphism.
The type of (.), (b -> c) -> (a -> b) -> a -> c, can't handle (x -> forall s. ST s [Int])
Previously there was an implementation of impredicative polymorphism which allowed GHC to handle that construct, but that has been removed (because it was unsatisfactory), so GHC 7 doesn't compile that anymore.
Anyone can suggest a solution?
Parentheses.
find i = runST ((`runContT` return) $ callCC $ \escape -> do return [])
Thanks!
AB
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 10 March 2011 18:24, Yves Parès
Why has the operator (.) troubles with a type like (forall s. ST s a)?
Why can't it match the type 'b' in (.) definition?
As explained by the email from SPJ that I linked to, instantiating a type variable (like 'b') with a polymorphic type (like 'forall s. ST s a' ) is called impredicative polymorphism. Since GHC-7 this is not supported any more because it was to complicated. Bas

On 10 March 2011 17:55, Bas van Dijk
On 10 March 2011 18:24, Yves Parès
wrote: Why has the operator (.) troubles with a type like (forall s. ST s a)?
Why can't it match the type 'b' in (.) definition?
As explained by the email from SPJ that I linked to, instantiating a type variable (like 'b') with a polymorphic type (like 'forall s. ST s a' ) is called impredicative polymorphism. Since GHC-7 this is not supported any more because it was to complicated.
AFAIK this decision was reversed because SPJ found a simple way to support them. Indeed, they work fine in 7.0.2 and generate warnings. Try it out: {{{ {-# LANGUAGE ImpredicativeTypes #-} module Impred where f :: Maybe (forall a. [a] -> [a]) -> Maybe ([Int], [Char]) f (Just g) = Just (g [3], g "hello") f Nothing = Nothing }}} Unfortunately, the latest user guide still reflects the old situation: http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extension... Cheers, Max

Excerpts from Max Bolingbroke's message of Fri Mar 11 05:15:34 -0500 2011:
AFAIK this decision was reversed because SPJ found a simple way to support them. Indeed, they work fine in 7.0.2 and generate warnings.
Correct. About a week-ish ago I submitted a patch to update the docs. Cheers, Edward

On 11 March 2011 11:15, Max Bolingbroke
On 10 March 2011 17:55, Bas van Dijk
wrote: On 10 March 2011 18:24, Yves Parès
wrote: Why has the operator (.) troubles with a type like (forall s. ST s a)?
Why can't it match the type 'b' in (.) definition?
As explained by the email from SPJ that I linked to, instantiating a type variable (like 'b') with a polymorphic type (like 'forall s. ST s a' ) is called impredicative polymorphism. Since GHC-7 this is not supported any more because it was to complicated.
AFAIK this decision was reversed because SPJ found a simple way to support them. Indeed, they work fine in 7.0.2 and generate warnings. Try it out:
Great! Unfortunately foo still doesn't type check in 7.0.2: foo :: (forall s. ST s a) -> a foo st = ($) runST st For the same reason I still need this ugly hack in usb-safe: http://hackage.haskell.org/packages/archive/usb-safe/0.12/doc/html/src/Syste... Bas
participants (6)
-
Anakim Border
-
Bas van Dijk
-
Daniel Fischer
-
Edward Z. Yang
-
Max Bolingbroke
-
Yves Parès