Skip to content

Use instance fields for superclasses (?) #1529

Open
@jespercockx

Description

@jespercockx

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 : SetF 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 fs

This 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions