GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-12T12:56:54Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/7395DefaultSignatures conflict with default implementations2019-07-12T12:56:54ZcgaebelDefaultSignatures conflict with default implementationsDefault signatures cannot be used with default implementations.
This is quite annoying for the hashable package, as we'd like to provide both options to the user.
See the attached test case.
<details><summary>Trac metadata</summary>
...Default signatures cannot be used with default implementations.
This is quite annoying for the hashable package, as we'd like to provide both options to the user.
See the attached test case.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | http://hpaste.org/77290 |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"DefaultSignatures conflict with default implementations","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1","keywords":["DefaultSignatures"],"differentials":[],"test_case":"http://hpaste.org/77290","architecture":"","cc":[""],"type":"Bug","description":"Default signatures cannot be used with default implementations.\r\n\r\nThis is quite annoying for the hashable package, as we'd like to provide both options to the user.\r\n\r\nSee the attached test case.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/10087DefaultSignatures: error message mentions internal name2020-02-11T12:47:33Zandreas.abelDefaultSignatures: error message mentions internal name```hs
{-# LANGUAGE DefaultSignatures #-}
class C a where
reflexive :: a -> Bool
default reflexive :: Eq a => a -> Bool
reflexive x = x == x
data D
instance C D where
-- /home/abel/play/haskell/bugs/DefaultSig.hs:10:10:
-- N...```hs
{-# LANGUAGE DefaultSignatures #-}
class C a where
reflexive :: a -> Bool
default reflexive :: Eq a => a -> Bool
reflexive x = x == x
data D
instance C D where
-- /home/abel/play/haskell/bugs/DefaultSig.hs:10:10:
-- No instance for (Eq D) arising from a use of ‘Main.$gdmreflexive’
-- In the expression: Main.$gdmreflexive
-- In an equation for ‘reflexive’: reflexive = Main.$gdmreflexive
-- In the instance declaration for ‘C D’
```
Error looks odd: The user has not written $gdmreflexive in his code.
TODO: Better error message.
Maybe this should just trigger a warning that method `reflexive` is undefined for instance `D` of `C`. Like when I remove the default method.
```
/home/abel/play/haskell/bugs/DefaultSig.hs:10:10: Warning:
No explicit implementation for
‘reflexive’
In the instance declaration for ‘C D’
```
It seems the semantics of a default signature is that each instance \*must\* implement this method.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.4 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"DefaultSignatures: error message mentions internal name","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.4","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"{{{#!hs\r\n{-# LANGUAGE DefaultSignatures #-}\r\n\r\nclass C a where\r\n reflexive :: a -> Bool\r\n default reflexive :: Eq a => a -> Bool\r\n reflexive x = x == x\r\n\r\ndata D\r\n\r\ninstance C D where\r\n\r\n-- /home/abel/play/haskell/bugs/DefaultSig.hs:10:10:\r\n-- No instance for (Eq D) arising from a use of ‘Main.$gdmreflexive’\r\n-- In the expression: Main.$gdmreflexive\r\n-- In an equation for ‘reflexive’: reflexive = Main.$gdmreflexive\r\n-- In the instance declaration for ‘C D’\r\n}}}\r\n\r\nError looks odd: The user has not written $gdmreflexive in his code.\r\n\r\nTODO: Better error message.\r\n\r\nMaybe this should just trigger a warning that method {{{reflexive}}} is undefined for instance {{{D}}} of {{{C}}}. Like when I remove the default method. \r\n\r\n{{{\r\n/home/abel/play/haskell/bugs/DefaultSig.hs:10:10: Warning:\r\n No explicit implementation for\r\n ‘reflexive’\r\n In the instance declaration for ‘C D’\r\n}}}\r\n\r\nIt seems the semantics of a default signature is that each instance *must* implement this method.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/17212Allow default methods to be implemented using template haskell2023-06-12T14:48:02ZMatthew PickeringAllow default methods to be implemented using template haskellIn conversations with @kosmikus he suggested that it would be nice to integrate default implementations with typed template haskell.
For example,
```
class Eq a where
eq :: a -> a -> Bool
default splice eq :: Generic a => Cod...In conversations with @kosmikus he suggested that it would be nice to integrate default implementations with typed template haskell.
For example,
```
class Eq a where
eq :: a -> a -> Bool
default splice eq :: Generic a => Code (a -> a -> Bool)
eq = _impl_
```
This has the massive advantage that the default implementation can be efficient than the usual `Data` or `Generics` based implementations.
There would need to be a GHC proposal related to this ticket but I write it down here in case anyone else finds it interesting.
Related to #12457Matthew PickeringMatthew Pickeringhttps://gitlab.haskell.org/ghc/ghc/-/issues/17224Backpack and instance defaults2020-10-18T02:01:41ZJohn EricsonBackpack and instance defaults[N.B. #17190 may be useful for some backstory.]
In Haskell today, if an associated type or data family has a default instance, hsig and hs-boot interfaces unconditionally opt-into that default. Unlike regular methods, the definition i...[N.B. #17190 may be useful for some backstory.]
In Haskell today, if an associated type or data family has a default instance, hsig and hs-boot interfaces unconditionally opt-into that default. Unlike regular methods, the definition is meaningful for an abstract instance because we use it at the type level. And yes, that means with dependent Haskell we will have this problem regular methods too, when everything can be reasoned about equationally (#13149).
Also, in the short term interfaces don't support type families so this is extra bad because it means one cannot use defaults with interfaces at all, not just when they intend to declare an instance that doesn't necessary opt into the default. (symptom with defaults #17190, underlying issue with type families #8441).
Given all that, I think we should choose a syntax for opting in or out of defaults in signatures. I furthermore think we should choose it real soon because #8441 is said by @ezyang to be had to implement, and I'd like to resolve #17190 in both a forwards-compatible fashion without crossing that minefield.
I see two choices:
1. `default foo, Foo` syntax to indicate a method (Type or term level) opts into a default.
2. Deprecate default methods. It keeps on requiring new syntax (default sigs, this) and isn't as flexible as deriving-via. Fix any outstanding issues with deriving-via and default methods.https://gitlab.haskell.org/ghc/ghc/-/issues/18259False-positive redundant-constraint warning on constrained default instance m...2020-07-14T14:19:18Zinfinity0False-positive redundant-constraint warning on constrained default instance methodTested on GHC 8.10.1:
```haskell
{-# LANGUAGE DefaultSignatures #-}
{-# OPTIONS_GHC -Werror -Wredundant-constraints #-}
class Base a where
myList :: [a]
default myList :: SubClass a => [a]
myList = defaultMyList
class Base a =>...Tested on GHC 8.10.1:
```haskell
{-# LANGUAGE DefaultSignatures #-}
{-# OPTIONS_GHC -Werror -Wredundant-constraints #-}
class Base a where
myList :: [a]
default myList :: SubClass a => [a]
myList = defaultMyList
class Base a => SubClass a where
myList2 :: [a]
defaultMyList :: SubClass a => [a]
defaultMyList = myList2
main :: IO ()
main = pure ()
```
The error is as follows:
~~~~
Test.hs:7:11: error: [-Wredundant-constraints, -Werror=redundant-constraints]
• Redundant constraint: Base a
• In the type signature for:
myList :: forall a. (Base a, SubClass a) => [a]
In the ambiguity check for ‘myList’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method: myList :: forall a. Base a => [a]
|
7 | default myList :: SubClass a => [a]
| ^^^^^^
~~~~
suggesting that some automatic process is adding `(Base a)` as an implicit constraint, but then this redundancy check is failing on the automatically-added constraint - which it shouldn't because the programmer can't do anything about it.
Adding `AllowAmbiguousTypes` does make the error go away, as the error message suggests, however the type is not ambiguous - there is no false-positive for `defaultMyList` with the same (source-level) signature. Adding `ConstrainedClassMethods` makes no difference.