[Agda] question about instance arguments

Peter Selinger selinger at mathstat.dal.ca
Thu Dec 4 14:42:02 CET 2014


Oops, I just read further in the Changelog, and I believe I found the
answer to my question:

 * Constructors of records and datatypes are automatically added to
   the instance table.

Also:

  Instance search takes into account all local bindings and all global
  'instance' bindings and the search is recursive.

This explains why "let e = eqBool in true == true" worked in my
previous example. I may have a shot of making some updates to the
reference manual. -- Peter

Peter Selinger wrote:
> 
> Hi Dominique and Andreas,
> 
> thanks for the replies. The actual behavior from Agda I experience is
> a bit erratic. Sometimes it will recognize identifiers in scope even
> without the "instance" keyword, and sometimes it won't. 
> 
> What is the syntax for using an "instance" keyword with data type
> definitions? Do you make the whole data type an instance, or just
> individual constructors? Consider the following example:
> 
> module InstanceTest where
>  
>   -- Zero is the empty set.
>   data Zero : Set where
> 
>   -- Succ A = A + 1. In other words, Succ, zero, and succ are what is
>   -- usually called Maybe, nothing, and just.
>   data Succ A : Set where
>     zero : Succ A
>     succ : A -> Succ A
> 
>   -- A subtyping relation: less-than-or-equal with respect to Succ.
>   data _<:_ : Set -> Set -> Set₁ where
>     <:-base : {A : Set} -> A <: A
>     <:-step : {A B : Set} -> {{p : A <: B}} -> A <: Succ B
> 
>   -- Cast from a smaller to a larger type.
>   cast : {A B : Set} -> {{p : A <: B}} -> A -> B
>   cast {{<:-base}} a = a
>   cast {{<:-step}} a = succ (cast a)
> 
>   test : {A : Set} -> A -> Succ (Succ (Succ A))
>   test x = cast x
> 
> The point about the subtyping relation <: is that if it exists, it is
> uniquely inhabited; however, with ordinary implicit arguments, Agda's
> type checker would not be able to infer this. With instance arguments,
> this works handsomely. Note how the subtyping was automatically
> inferred in the definition of "test".
> 
> However, I have not used any "instance" keywords here. Does this
> contradict the stated behavior of Agda 2.4.2? Also, putting an
> "instance" keyword before either "data" or "<:-base" or "<:-step"
> gives a parsing error in all cases. So is the above syntax still
> considered correct for Agda 2.4.2? If not, what is the alternative?
> 
> Thanks, -- Peter
> 
> Dominique Devriese wrote:
> > 
> > Peter,
> > 
> > Firstly, the problem you're having is a result of the changes to
> > instance argument semantics that have been made in Agda 2.4.2, which
> > are not yet reflected in the reference manual and some of the error
> > messages.  You can look at
> > 
> > https://github.com/agda/agda/blob/2.4.2.2/CHANGELOG
> > 
> > (look for "Instance search") to see what has been changed.
> > 
> > 2014-12-04 2:28 GMT+01:00 Peter Selinger <selinger at mathstat.dal.ca>:
> > > I'm trying to learn to use instance arguments, and I tried a first
> > > example, essentially taken from the reference manual:
> > >
> > > http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.Modell> ingTypeClassesWithInstanceArguments
> > >
> > > Unfortunately, I cannot get it to work. Probably I am overlooking
> > > something terribly simple. I am using Agda version 2.4.2.2, freshly
> > > installed via Cabal.
> > 
> > Yes, the reference manual needs updating.
> > 
> > > Here's my file:
> > >
> > > module EqTest where
> > >
> > >   data Bool : Set where
> > >     true : Bool
> > >     false : Bool
> > >
> > >   eq : Bool -> Bool -> Bool
> > >   eq true true = true
> > >   eq false false = true
> > >   eq _ _ = false
> > >
> > >   record Eq (t : Set) : Set where
> > >     field
> > >       _==_ : t -> t -> Bool
> > >
> > >   open Eq {{...}}
> > >
> > >   eqBool : Eq Bool
> > >   eqBool = record { _==_ = eq }
> > 
> > Essentially, you need to change this to
> >    instance eqBool : Eq Bool
> >    eqBool = record { _==_ = eq }
> > 
> > >   test1 = true == true
> > 
> > > The error message I receive, in the test1 line, is:
> > >
> > > /home/selinger/projects/lang/agda/EqTest.agda:21,16-18
> > > No variable of type Eq Bool was found in scope.
> > > when checking that true true are valid arguments to a function of
> > > type {t : Set} {{r : Eq t}} → t → t → Bool
> > >
> > > This seems contradictory, since the variable eqBool is indeed in
> > > scope.
> > 
> > It would probably be a good idea to change this error message to
> > something like "... was found using the instances in scope"?
> > 
> > > If I replace the eqBool definition by a postulate, as in the
> > > reference manual,
> > >
> > >   postulate eqBool : Eq Bool
> > >
> > > I get the same error message.
> > 
> > Yes, this makes no difference.
> > 
> > > On the other hand, if I write
> > >
> > >   test1 = let e = eqBool in true == true
> > >
> > > the error disappears in both cases.
> > 
> > Ah, this surprises me, I thought you had to annotate let-bound
> > variables as well using instance under the new schem.
> > 
> > > On the other hand, this does not
> > > work:
> > >
> > >   test1 = true == true
> > >     where e = eqBool
> > 
> > This is expected under the new semantics.
> > 
> > > The reference manual says:
> > >
> > > "A candidate expression is any identifier (possibly applied to a
> > > hidden argument) in scope (either imported or defined previously in
> > > the file) or in the context (e.g. section arguments or arguments of
> > > the current function)."
> > >
> > > My example seems to contradict that. Is it a bug?
> > 
> > Yes, it is a bug in the reference manual :).  It should be updated to
> > reflect the new semantics.
> > 
> > Dominique
> > 
> 
> 



More information about the Agda mailing list