| ... | ... | @@ -66,3 +66,65 @@ textual ordering of the default declaration clauses. |
|
|
|
|
|
|
|
- can not exactly replicate behavior of existing defaulting mechanism, but can come close.
|
|
|
|
- might hide errors, an optional warning on defaulting should be possible.
|
|
|
|
|
|
|
|
## Proposal 2
|
|
|
|
|
|
|
|
|
|
|
|
Change the syntax of the defaulting clause from:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
topdecl -> default ( type_1 , ... , type_n )
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
to
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
topdecl -> default ( tycls_1 => type_1 , ... , tycls_n => type_n )
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Semantically, which type is chosen is determined by the class context at the choice point (after context simplification). If there is no unique choice, for instance because more than one class-with-a-default is mentioned in the context (and their default types are different), then it is a static error. Note that it is OK to have several classes in the context of the defaultable value, provided only one of them is declared to yield a default type, or if more than one yields a type, those types are the same. Choosing a default after context simplification means that no conflicts between super- and sub-classes can arise.
|
|
|
|
|
|
|
|
|
|
|
|
The current Haskell'98 default-default behaviour can be specified as:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
default ( Num => Integer
|
|
|
|
, Real => Integer
|
|
|
|
, Enum => Integer
|
|
|
|
, Integral => Integer
|
|
|
|
, Fractional => Double
|
|
|
|
, RealFrac => Double
|
|
|
|
, Floating => Double
|
|
|
|
, RealFloat => Double
|
|
|
|
)
|
|
|
|
```
|
|
|
|
|
|
|
|
### Pros
|
|
|
|
|
|
|
|
- less ad hoc than current method
|
|
|
|
- overcomes the Hat transformation problem
|
|
|
|
- does not rely on textual ordering of decl
|
|
|
|
- permits defaulting of user-defined classes, not just Prelude ones
|
|
|
|
|
|
|
|
### Cons
|
|
|
|
|
|
|
|
- not sure if this exactly captures the existing Haskell'98 module (but because defaults are currently limited to Prelude classes, it probably does).
|
|
|
|
|
|
|
|
## Proposal 3
|
|
|
|
|
|
|
|
|
|
|
|
Orthogonal to the issue of how to specify defaults, is the question of whether they should be module-local, or if instead we should treat them like instance declarations - global in scope. One can also imagine permitting explicit lexical scoping, i.e. a local override of the defaults, purely within a single function definition.
|
|
|
|
|
|
|
|
|
|
|
|
Concrete proposal: a default decl can occur anywhere that a type signature would be valid, and has the same scope. However, because default decls cannot be named, all default topdecls must be unique throughout a program. By contrast, a local default decl can override one at an outer scope, but only within its own inner scope.
|
|
|
|
|
|
|
|
### Pros
|
|
|
|
|
|
|
|
- Arguably, when user-defined classes and types are involved, it is a lot clearer to make any necessary default decls once only, in a library, and just have them apply everywhere, rather than to require end-users to understand the issues and make their own default decls.
|
|
|
|
- Having consistent defaults throughout a program is semantically nicer (but you still get the opportunity to override them locally if you _really_ need to - just like with operator fixities).
|
|
|
|
|
|
|
|
### Cons
|
|
|
|
|
|
|
|
- Changes the Haskell'98 behaviour (where defaults are module-local). Question: Do any real programs actually rely on the Haskell'98 spec here? |