-
Notifications
You must be signed in to change notification settings - Fork 259
Description
I found that the current way of defining a class that has a superclass does not play nice with instance search. Here is a small example using the Alternative typeclass and its ApplicativeZero superclass:
open import Data.List.Base using (List; []; _∷_; [_])
open import Function.Base
open import Level using (Level)
open import Category.Functor renaming (RawFunctor to Functor)
open import Category.Applicative
renaming ( RawApplicative to Applicative
; RawApplicativeZero to ApplicativeZero
; RawAlternative to Alternative
)
open Functor {{...}} using (_<$>_)
open Applicative {{...}} using ()
open ApplicativeZero {{...}} using () renaming (∅ to empty)
open Alternative {{...}} using () renaming (_∣_ to _<|>_)
variable
ℓ ℓ′ : Level
A B C : Set ℓ
F M : Set ℓ → Set ℓ′
choice1 : {{_ : Alternative F}} → List (F A) → F A
choice1 [] = empty
where instance applicativeZeroF = Alternative.applicativeZero it
choice1 (f ∷ []) = f
choice1 (f ∷ fs) = f <|> choice1 fsThis example is accepted, but it is awkward to have to declare the instance applicativeZeroF locally.
In the Agda user manual, it is recommended to use instance fields for encoding superclasses: https://agda.readthedocs.io/en/v2.6.2/language/record-types.html#instance-fields. Unfortunately Agda currently does not provide a way to change a normal field to an instance field when importing a module. So the only solution I can see is to change the definition of these record types in the standard library to use instance fields from the beginning. Making these fields into instance fields should not change anything for people not using instance search, except that the type of the record constructor changes. But actually RawIAlternative currently does not have a record constructor, so AFAICT the change should be 100% backwards compatible.
Also pinging @UlfNorell since he might know alternative solutions.