Typeclasses and implicit parameters

{-# OPTIONS -fglasgow-exts #-} -- G'day everyone. -- This is okay. f1 :: (?foo :: String) => String f1 = ?foo -- So is this. f2 :: (Show a, ?foo :: a) => a -> String f2 _ = show ?foo -- Hugs allows this. GHC rejects it on the grounds that "a" is unused -- on the right-hand side of the (=>). I think this is arguably a bug -- in GHC. f3 :: (Show a, ?foo :: a) => String f3 = show ?foo -- GHC rejects this. Hugs compiles it, but I can't call it as -- let ?foo = "Hello" in show Foo -- -- Is there a good reason to disallow this? data Foo = Foo instance (?foo :: String) => Show Foo where showsPrec _ Foo = showString ?foo . showString "Foo" -- Cheers, -- Andrew Bromage

| -- Hugs allows this. GHC rejects it on the grounds that "a" is unused | -- on the right-hand side of the (=>). I think this is arguably a bug | -- in GHC. | f3 :: (Show a, ?foo :: a) => String | f3 = show ?foo Hugs is right here. GHC 6.8 accepts this too, and has done for some time; there's even a test in the test suite (tc218). | -- GHC rejects this. Hugs compiles it, but I can't call it as | -- let ?foo = "Hello" in show Foo | -- | -- Is there a good reason to disallow this? | data Foo = Foo | | instance (?foo :: String) => Show Foo where | showsPrec _ Foo = showString ?foo . showString "Foo" This should be illegal. The way in which implicit parameters are bound depends on the call site of teh overloaded function. E.g. the call site of f3 above affects the value of ?foo. For an instance declaration, the "call site" is unknown -- it's wherever the type checker chooses to simplify the constraint. No implicit parameters in instance contexts! This is documented in GHC's user manual Section 7.4.6.1 http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html... Simon

G'day all.
Quoting Simon Peyton-Jones
| -- GHC rejects this. Hugs compiles it, but I can't call it as | -- let ?foo = "Hello" in show Foo | -- | -- Is there a good reason to disallow this? | data Foo = Foo | | instance (?foo :: String) => Show Foo where | showsPrec _ Foo = showString ?foo . showString "Foo"
This should be illegal. The way in which implicit parameters are bound depends on the call site of teh overloaded function. E.g. the call site of f3 above affects the value of ?foo.
Yes, I've read the manual section on this. For completeness, here's the final solution, courtesy of int-e (whose real name I don't know; sorry), which is much more elegant than I expected: -- Type hackery import GHC.Exts (unsafeCoerce#) newtype Mark m a = Mark { unMark :: a } toDummy :: Mark n t -> (n -> t) toDummy (Mark x) _ = x fromDummy :: (n -> t) -> Mark n t fromDummy f = Mark (f undefined) -- And now, the real code class StringAsType s where reifiedString' :: Mark s String withString :: (StringAsType s) => s -> (String -> a) -> a withString s k = k (toDummy reifiedString' s) getString :: (StringAsType s) => s -> String getString s = withString s id bindString :: (forall s. StringAsType s => Mark s a) -> String -> a bindString = unsafeCoerce# mkStringAsType :: String -> (forall s. StringAsType s => s -> a) -> a mkStringAsType s f = bindString (fromDummy f) s -- ReifiedString can now be used as an instance context That higher-rank type makes all the difference. Cheers, Andrew Bromage

ajb@spamcop.net wrote in article <20070906064921.86dtrwt0v4go4s08@webmail.spamcop.net> in gmane.comp.lang.haskell.cafe:
That higher-rank type makes all the difference.
Yes. You can even do this portably, using nothing "unsafe", with Dylan Thurston's technique: Oleg Kiselyov and Chung-chieh Shan. 2004. Functional pearl: Implicit configurations -- or, type classes reflect the value of types. In Proceedings of the 2004 Haskell workshop, 33-44. New York: ACM Press. http://www.cs.rutgers.edu/~ccshan/prepose/ -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig We're not "teaching Scheme." I spend about an hour teaching Scheme, and for the rest of the semester I /use/ Scheme to teach /computer science/. Brian Harvey (UC Berkeley) on comp.lang.scheme. Aug 22, 2007.

On Thu, Sep 06, 2007 at 06:49:21AM -0400, ajb@spamcop.net wrote:
For completeness, here's the final solution, courtesy of int-e (whose real name I don't know; sorry), which is much more elegant than I
Bertram Felgenhauer
bindString :: (forall s. StringAsType s => Mark s a) -> String -> a bindString = unsafeCoerce#
Oooh! So evil, I love it. Stefan
participants (4)
-
ajb@spamcop.net
-
Chung-chieh Shan
-
Simon Peyton-Jones
-
Stefan O'Rear