| It seems that from GHC 7.4, the prohibition on implicit parameter
| constraints in instance declarations has been relaxed. The program below
| gives the error "Illegal constraint ?fooRev::Bool" in GHC 7.2.1 but
| loads fine in GHC 7.4.2 and GHC 7.6.2.

I don't I changed this intentionally, but the type system has been refactored 
so massively over the years (it's way better than before!) that it's entirely 
possible it happened as an unintentional consequence.

There is actually a good reason.  For a function
        f :: (?x::Int) => blah
it's clear where 'f' occurs, and hence which ?x you get:

        g y = let ?x=4 in ....(let ?x=5 in ...f...) ...f...

The first call to 'f' sees ?x=5, and the second sees ?x=4.  IP bindings are 
like local instance declarations.

But suppose we had
        class D a where { op :: a -> a }
        instance (?x::Int) => D Int where ...
        g y = let ?x=4 in ....(let ?x=5 in ...op (y::Int)...) ......

The call to op gives rise to a constraint (D Int).  Where does that constraint 
get solved?  Right at the call to 'op'?  Then it'll see ?x=5?  or further out?  
then it'll see ?x=4.  Or at top level?  Then it won't see a binding for ?x at 
all.

This is bad. Currently the site at which instance declarations are used isn't 
important, but now it would become important, and the semantics of the program 
would depend on it.

I think I should disable it again!

Simon

| -----Original Message-----
| From: Glasgow-haskell-users [mailto:glasgow-haskell-users-
| [email protected]] On Behalf Of Ganesh Sittampalam
| Sent: 16 July 2013 07:21
| To: [email protected]
| Subject: implicit params in instance contexts
| 
| Hi,
| 
| It seems that from GHC 7.4, the prohibition on implicit parameter
| constraints in instance declarations has been relaxed. The program below
| gives the error "Illegal constraint ?fooRev::Bool" in GHC 7.2.1 but
| loads fine in GHC 7.4.2 and GHC 7.6.2.
| 
| I can't spot anything about this in the release notes, and the
| documentation
| (http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/other-type-
| extensions.html#idp49069584)
| still says "You can't have an implicit parameter in the context of a
| class or instance declaration."
| 
| So I wonder if this happened by accident, perhaps as part of the
| ConstraintKinds work or similar?
| 
| I've wanted this feature a few times so if it's going to stay I might
| start using it. However it is a bit dangerous, so if it was added by
| accident it might warrant some discussion before deciding to keep it.
| For example as the value "set2" below shows, it can be used to violate
| datatype invariants.
| 
| Cheers,
| 
| Ganesh
| 
| 
| {-# LANGUAGE ImplicitParams #-}
| module Ord where
| 
| import Data.Set ( Set )
| import qualified Data.Set as Set
| 
| newtype Foo = Foo Int
|     deriving (Eq, Show)
| 
| instance (?fooRev :: Bool) => Ord Foo where
|     Foo a `compare` Foo b =
|         if ?fooRev then b `compare` a else a `compare` b
| 
| set1 = let ?fooRev = False in Set.fromList [Foo 1, Foo 3]
| 
| set2 = let ?fooRev = True in Set.insert (Foo 2) set1
| -- Ord> set2
| -- fromList [Foo 2,Foo 1,Foo 3]
| 
| _______________________________________________
| Glasgow-haskell-users mailing list
| [email protected]
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

_______________________________________________
Glasgow-haskell-users mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to