[GHC] #7624: Handling ImplicitParams in Instance Declaration

#7624: Handling ImplicitParams in Instance Declaration ------------------------------+--------------------------------------------- Reporter: philipjf | Owner: Type: bug | Status: new Priority: normal | Component: Documentation Version: 7.6.1 | Keywords: ImplicitParams Os: Unknown/Multiple | Architecture: Unknown/Multiple Failure: Documentation bug | Blockedby: Blocking: | Related: ------------------------------+--------------------------------------------- The GHC documentation states that ImplicitParam's may not be used in class or instance declaration constraints. see for example http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/other-type- extensions.html In practice though, at least on the Mac, all recent version of GHC have permitted such instances. At the very least the documentation should make clear that the compiler might permit such instances, but they have undefined behaviour. Ideally, these would simply be permitted. [http://joyoftypes.blogspot.com/2013/01/using-compiler-bugs-for-fun-and- profit.html Why I think the (undocumented) current behavior is correct] -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7624 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7624: Handling ImplicitParams in Instance Declaration ---------------------------------+------------------------------------------ Reporter: philipjf | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Documentation | Version: 7.6.1 Keywords: ImplicitParams | Os: Unknown/Multiple Architecture: Unknown/Multiple | Failure: Documentation bug Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | ---------------------------------+------------------------------------------ Changes (by simonpj): * difficulty: => Unknown Comment: I think the issue is this. Consider this: {{{ class C a where op :: a -> a instance (?x:[a]) => C [a] where op _ = ?x foo y xs = let ?x = [y] in (length xs, op xs) }}} From the instance declaration we get a dictionary-constructing function with type {{{ dfunCList :: forall a. (?x:a) -> C [a] }}} What type should be inferred for `foo`? I can think of three. I give there with their translation into System F so you can see what proof strategy I've used to solve the constraints. {{{ foo1 :: C [a] => b -> [a] -> [a] foo1 a (d:C [a]) (y:b) (xs:[a]) = let _x = [y] in (length a xs, op a d xs) foo2 :: (?x:a} => b -> [a] -> [a] foo2 a b (?x:a) (y:b) (xs:[a]) = let _x = [y] in (length a xs, op a (dfunCList a ?x) xs) foo3 :: a -> [a] -> [a] foo3 a (y:a) (xs:[a]) = let ?x = [y] in (length a xs, op a (dfunCList a ?x) xs) }}} Notice that there is no most-general type. It all depends when we make use of the `dfunCList` dictionary construction, and, even when we have done so, whether we take advantage of the local binding for `?x`. I suppose we could just say "GHC will randomly decide which of these three to pick, but its hardly satisfactory! Adding implicit parameters as superclasses is at least as problematic, perhaps more so. In short, I'm unconvinced! Simon -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7624#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7624: Handling ImplicitParams in Instance Declaration ---------------------------------+------------------------------------------ Reporter: philipjf | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Documentation | Version: 7.6.1 Keywords: ImplicitParams | Os: Unknown/Multiple Architecture: Unknown/Multiple | Failure: Documentation bug Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | ---------------------------------+------------------------------------------ Comment(by philipjf): Hm... I'm not sure that is different from what happen currently with local evidence and/or implicitParams {{{ {-# LANGUAGE GADTs, ImplicitParams #-} class C a where op :: a -> a data X a where X :: C a => X a fooGADT X xs = (length xs, op xs) fooIP xs ys = let ?op = const ys in (length xs, ?op xs) }}} GHC infers types for both of these terms, and has rules to do it. We have `fooGADT :: C [a] => X t -> [a] -> (Int, [a])` inferred, but this type will be rejected if we give it as an annotation because it has a non type variable argument, and is no more general than `fooGADT :: X [a] -> [a] -> (Int, [a])`. Actually, giving a type annotation is not good enough in the presence of local type information to determine behavior {{{ fooGADT' :: X [a] -> X [a] -> [a] -> (Int,[a]) fooGADT' X X xs = (length xs, op xs) }}} or the really unclear {{{ data X' a where X' :: (?op :: a -> a) => X' a fooGADT'' :: X' [a] -> X' [a] -> [a] -> (Int,[a]) fooGADT'' X' X' xs = (length xs, ?op xs) whatShouldThisDo :: [a] -> [a] -> (Int, [a]) whatShouldThisDo xs ys = let a = (let ?op = const ys in X') b = (let ?op = id in X') in fooGADT'' a b xs }}} The point is, I think this is a general problem, and not one unique to allowing implicits in instances. With orphan instnaces you don't need implicit params at all to make this problem show up. Allowing implicits in class constraints seems more suspect though. -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7624#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#7624: Handling ImplicitParams in Instance Declaration ---------------------------------+------------------------------------------ Reporter: philipjf | Owner: Type: bug | Status: new Priority: normal | Milestone: 7.8.1 Component: Documentation | Version: 7.6.1 Keywords: ImplicitParams | Os: Unknown/Multiple Architecture: Unknown/Multiple | Failure: Documentation bug Difficulty: Unknown | Testcase: Blockedby: | Blocking: Related: | ---------------------------------+------------------------------------------ Changes (by igloo): * milestone: => 7.8.1 -- Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7624#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC