forked from Orchid/orchid
Rewritten deleted impls section from notebook
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
In Orchid, types and typeclasses aren't distinguished. Impls are the equivalent of typeclass
|
||||
implementations. The syntax looks like this:
|
||||
|
||||
```orc
|
||||
impl typeExpression [by name [over overriddenName, furtherOverriddenNames...]] via valueExpression
|
||||
```
|
||||
|
||||
An impl can be considered a candidate for an auto if its typeExpression unifies with the auto's type
|
||||
An impl candidate can be used to resolve an auto if
|
||||
- typeExpression unifies with the auto's type
|
||||
- it is not present in any other matching impl's override tree
|
||||
- all other candidates are present in its override tree
|
||||
|
||||
In Rust impls can be placed in one of two modules; the trait owner, and the type owner. In orchid
|
||||
that is not the case, so two additional possibilities arise that Rust's orphan rules prevent.
|
||||
|
||||
## Foster impls
|
||||
|
||||
If it doesn't make sense for either of the participants to acknowledge the others, foster impls
|
||||
can be created which don't own any of the participant symbols.
|
||||
|
||||
```orc
|
||||
import GenericModule::Typeclass
|
||||
import SpecificModule::(Type, function)
|
||||
|
||||
impl Typeclass Type by fosterTypeclassType via function
|
||||
```
|
||||
|
||||
Foster impls can be placed in foster packages whose sole purpose is to glue packages together, or
|
||||
they can be embedded in usercode.
|
||||
|
||||
## Arbiter impls
|
||||
|
||||
If multiple foster impls exist for a given package, or if you use a foster package but one of the
|
||||
parents involved has added an impl in the mean time, ambiguities arise. To resolve these, arbiter
|
||||
impls can be used to decide which impl's value will win.
|
||||
|
||||
``` orc
|
||||
import BadModule::badImpl
|
||||
import GoodModule::goodImpl
|
||||
import GenericModule::Typeclass
|
||||
import SpecificModule::Type
|
||||
|
||||
impl Typeclass Type by arbiterGoodModuleTypeclassType over goodImpl, badImpl via goodImpl
|
||||
```
|
||||
|
||||
Notice that goodImpl appears both as a value and an impl name. Named impls are always also
|
||||
exported as value substitution rules, specifically to account for situations where you want to use
|
||||
them despite auto resolution. They can be referenced in arbiter rules, exception rules for more
|
||||
general impls, auto-parameter overrides, and directly used as values in code.
|
||||
|
||||
The more common and less hacky use case for arbiter rules is when a very general rule from a
|
||||
general package needs to be overridden by a more specific rule from a deep ancestor.
|
||||
|
||||
---
|
||||
|
||||
In all cases, these problems represent a concern gap or overlap and should be eventually resolved
|
||||
by the authors of the original packages. The purpose of foster and arbiter rules is to not stall
|
||||
the ecosystem on a trivial conflict of concepts and to make adding dependencies less risky.
|
||||
It should still take some effort to maintain a large dependency list, but the risk of complete
|
||||
blockage becomes a more manageable constant effort.
|
||||
Reference in New Issue
Block a user