[Agda] Agda type inference oddity on functions
Alan Jeffrey
ajeffrey at bell-labs.com
Mon Sep 27 17:49:53 CEST 2010
Hi everyone,
An issue in the context of being able to implement functions with
default values for implicit parameters (the "Pie In The Sky" thread).
There may be a roadblock, caused by some odd behaviour around when Agda
can infer that a term has function type.
Attached is a program that defines a function whose only effect is to
enforce that its argument is a function. The version in the file is
level-polymorphic and deals with dependent functions, but its simpler
cousin is:
isFun : {A B : Set} -> (A -> B) -> (A -> B)
isFun f = f
Then we can show that there are contexts such that:
a) isFun (lambda x -> x) type-infers, but (lambda x -> x) does not.
b) (isFun f x) type-infers, but (f x) does not.
That is, the type inference engine doesn't infer that lambda-terms or
applied terms have function type, which seems odd to me.
Also, eta-expansion can cause terms to fail to type-infer, that is there
are types such that:
ok : A -> B -> C
ok f = f -- type-infers
nok : A -> B -> C
nok f x = f x -- fails
Bug, or feature? (I had a look in the issue-tracker, didn't find it
there...)
A.
-------------- next part --------------
{-# OPTIONS --universe-polymorphism #-}
open import Level
open import Data.Bool
open import Data.Nat
module Odd where
-- This module demonstrates that the Agda type inference algorithm
-- doesn't add constraints in that f is a function, even when
-- f is a lambda term or has been applied. Concretely, we define
-- a function isFun, such that (isFun f) returns f, but only
-- typechecks when f is a function. Then we show contexts where
-- (isFun (λ x â x)) typechecks, but (λ x â x) does not, and where
-- (isFun f x) typechecks, but (f x) does not.
-- Oh, and we also show that eta-expansion can turn a typechecking
-- term into a non-typechecking term.
isFun : {a b : Level} â {A : Set a} â {F : A â Set b} â
((a : A) â (F a)) â ((a : A) â (F a))
isFun f = f
-- Example follows. Note that F is injective, and the
-- inference algorithm recognizes it as such.
F : Bool â Set
F true = â â â
F false = â
A : Set
A = {b : Bool} â (F b)
bool : {b : Bool} â (F b) â Bool
bool {b} x = b
-- x1 fails, x2 passes: Agda can't infer that a λ-term is a function
x1 : Bool
x1 = bool (λ x â x)
x2 : Bool
x2 = bool (isFun (λ x â x))
-- x3 fails, x4 passes: Agda can't infer that an applied term is a function
x3 : A â â â â
x3 f x = f x
x4 : A â â â â
x4 f x = isFun f x
-- And just for some extra weirdness, eta-contracting
-- x3 causes it to typecheck!
x5 : A â â â â
x5 f = f
More information about the Agda
mailing list