
I have to port the following piece of code to ghc-6.6: [...] addSimpleFallOut :: IO a -> IO (Either String a) simpleFallOutId :: ObjectID (simpleFallOutId, addSimpleFallOut) = mkSimpleFallOut mkSimpleFallOut :: (ObjectID,IO a -> IO (Either String a)) mkSimpleFallOut = unsafePerformIO newFallOut {-# NOINLINE mkSimpleFallOut #-} newFallOut :: IO (ObjectID, IO a -> IO (Either String a)) [...] ghc-6.5.20060919 reports: Couldn't match expected type `forall a. IO a -> IO (Either String a)' against inferred type `IO a -> IO (Either String a)' Expected type: (ObjectID, forall a1. IO a1 -> IO (Either String a1)) Inferred type: (ObjectID, IO a -> IO (Either String a)) In the expression: mkSimpleFallOut In a pattern binding: (simpleFallOutId, addSimpleFallOut) = mkSimpleFallOut I can make the code compile by rewriting the pair as: simpleFallOutId = fst mkSimpleFallOut addSimpleFallOut = snd mkSimpleFallOut However, in this case I have inlined mkSimpleFallOut manually! Does this matter? If so, how could I rewrite the above code? Cheers Christian

Hello Christian, Thursday, September 21, 2006, 12:55:45 PM, you wrote:
I have to port the following piece of code to ghc-6.6:
may be explicit foralls would help?
mkSimpleFallOut :: (ObjectID,IO a -> IO (Either String a))
try mkSimpleFallOut :: (ObjectID, forall a. IO a -> IO (Either String a)) and mkSimpleFallOut :: forall a. (ObjectID, IO a -> IO (Either String a))
newFallOut :: IO (ObjectID, IO a -> IO (Either String a))
also two variants -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin schrieb:
may be explicit foralls would help?
mkSimpleFallOut :: (ObjectID,IO a -> IO (Either String a))
try mkSimpleFallOut :: (ObjectID, forall a. IO a -> IO (Either String a))
yes this variant works!
newFallOut :: IO (ObjectID, IO a -> IO (Either String a))
together with: newFallOut :: IO (ObjectID, forall a. IO a -> IO (Either String a)) but fails with ghc-6.4.2: parse error on input `forall' (column 30) Christian

Aha! You are the second real customer to discover a change I made to GHC 6.6, namely that pattern bindings are not generalised. It's a documented change (see "Monomorphic pattern bindings" in the 6.6 user manual), but it means that 6.6 is not, by default, exactly Haskell 98. To recover the previous behaviour use -fno-mono-pat-binds. There is a reason for the change. Generalising pattern bindings is a rather significant complication in the language design. My theory is that it's a feature that is almost never used -- and on the rare occasion that it is used, you can get around it. You can solve your problem in three ways * -fno-mono-pat-binds * use the fst/snd thing as you suggest * put the polymorphic function in the tuple as Bulat suggested (this makes use of GHC's new ability to impredicative polymorphism. Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users- | bounces@haskell.org] On Behalf Of Christian Maeder | Sent: 21 September 2006 09:56 | To: GHC Users Mailing List | Subject: compiler change | | I have to port the following piece of code to ghc-6.6: | | [...] | addSimpleFallOut :: IO a -> IO (Either String a) | simpleFallOutId :: ObjectID | (simpleFallOutId, addSimpleFallOut) = mkSimpleFallOut | | mkSimpleFallOut :: (ObjectID,IO a -> IO (Either String a)) | mkSimpleFallOut = unsafePerformIO newFallOut | {-# NOINLINE mkSimpleFallOut #-} | | newFallOut :: IO (ObjectID, IO a -> IO (Either String a)) | [...] | | ghc-6.5.20060919 reports: | Couldn't match expected type `forall a. | IO a -> IO (Either String a)' | against inferred type `IO a -> IO (Either String a)' | Expected type: (ObjectID, | forall a1. IO a1 -> IO (Either String a1)) | Inferred type: (ObjectID, IO a -> IO (Either String a)) | In the expression: mkSimpleFallOut | In a pattern binding: | (simpleFallOutId, addSimpleFallOut) = mkSimpleFallOut | | I can make the code compile by rewriting the pair as: | | simpleFallOutId = fst mkSimpleFallOut | addSimpleFallOut = snd mkSimpleFallOut | | However, in this case I have inlined mkSimpleFallOut manually! Does this | matter? If so, how could I rewrite the above code? | | Cheers Christian | | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Simon Peyton-Jones schrieb:
Aha! You are the second real customer to discover a change I made to
"customer" sounds as if I will have to pay next time.
GHC 6.6, namely that pattern bindings are not generalised. It's a documented change (see "Monomorphic pattern bindings" in the 6.6 user manual), but it means that 6.6 is not, by default, exactly Haskell 98. To recover the previous behaviour use -fno-mono-pat-binds.
thanks for pointing this out!
You can solve your problem in three ways * -fno-mono-pat-binds * use the fst/snd thing as you suggest * put the polymorphic function in the tuple as Bulat suggested (this makes use of GHC's new ability to impredicative polymorphism.
Last question, is using "fst/snd" really a problem as I suspected by using the constant twice? (I actually didn't explicitly inline the constant by two calls of unsafePerfromIO.) Thanks again, Christian
| -----Original Message-----
| mkSimpleFallOut :: (ObjectID,IO a -> IO (Either String a)) | mkSimpleFallOut = unsafePerformIO newFallOut | {-# NOINLINE mkSimpleFallOut #-} | | newFallOut :: IO (ObjectID, IO a -> IO (Either String a))
| simpleFallOutId = fst mkSimpleFallOut | addSimpleFallOut = snd mkSimpleFallOut | | However, in this case I have inlined mkSimpleFallOut manually! Does this | matter? If so, how could I rewrite the above code?

| Last question, is using "fst/snd" really a problem as I suspected by | using the constant twice? (I actually didn't explicitly inline the | constant by two calls of unsafePerfromIO.) Using a constant twice should not duplicate the work of computing it, if that's what you mean S
participants (3)
-
Bulat Ziganshin
-
Christian Maeder
-
Simon Peyton-Jones