Reputation: 27636
In the following code, the definition of μ₁
is accepted by Agda as a strictly positive functor, which makes sense. If I tie the knot via a product, as in μ₂
, it is still accepted. However, if I try to go via a vector, as in μ₃
, it is not accepted anymore.
data F : Set where
X : F
⟦_⟧₁ : F → Set → Set
⟦ X ⟧₁ A = A
data μ₁ (f : F) : Set where
Fix₁ : ⟦ f ⟧₁ (μ₁ f) → μ₁ f
open import Data.Product
⟦_⟧₂ : F → (Set × Set) → Set
⟦ X₁ ⟧₂ (A , _) = A
open import Data.Unit
data μ₂ (f : F) : Set where
Fix₂ : ⟦ f ⟧₂ (μ₂ f , ⊤) → μ₂ f
open import Data.Nat
open import Data.Vec
⟦_⟧₃ : ∀ {n} → F → Vec Set (suc n) → Set
⟦ X ⟧₃ (A ∷ _) = A
data μ₃ (f : F) : Set where
Fix₃ : ⟦ f ⟧₃ [ μ₃ f ] → μ₃ f
The error message for μ₃
is
μ₃ is not strictly positive, because it occurs
in the third argument to ⟦_⟧₃
in the type of the constructor Fix₃
in the definition of μ₃.
What is the fundamental difference between μ₂
and μ₃
? Is there a way to get something like μ₃
working?
Upvotes: 2
Views: 51
Reputation: 12715
I'm mostly guessing. _×_
is a record
and Vec
is a data
. Agda rejects μ₂
, when _×_
is defined as a data
:
data Pair (A B : Set₁) : Set₁
where pair : A -> B -> Pair A B
⟦_⟧₃ : F → Pair Set Set → Set
⟦ X ⟧₃ (pair A _) = A
data μ₃ (f : F) : Set where
Fix₃ : ⟦ f ⟧₃ (pair (μ₃ f) ⊤) → μ₃ f
Results in "μ₃
is not strictly positive, because it occurs...". But if you define ⟦_⟧₃
as
⟦_⟧₃ : F → Pair Set Set → Set
⟦ X ⟧₃ _ = ⊤
or
⟦_⟧₃ : F → Pair Set Set → Set
⟦ _ ⟧₃ (pair A _) = A
then everything is OK (your μ₂
is a bit misleading, since there is no pattern matching on F
too). In the second case Agda just normalizes the expression, since there is no pattern matching on the first argument and the second is in the WHNF, so ⟦_⟧₃
is totally eliminated. But I don't know, how Agda resolves the first case. Something ad hoc, I suppose.
Your μ₂
typechecks, because Agda eliminates pattern matching on records:
map : {A B : Set} {P : A → Set} {Q : B → Set} (f : A → B) → (∀ {x} → P x → Q (f x)) → Σ A P → Σ B Q map f g (x , y) = (f x , g y)
The clause above is internally translated into the following one:
map f g p = (f (Σ.proj₁ p) , g (Σ.proj₂ p))
So it's just like the
⟦_⟧₃ : F → Pair Set Set → Set
⟦ X ⟧₃ _ = ⊤
case.
Also, ⟦_⟧₃
will typecheck, if you remove pattern matching on the first argument.
UPDATE
No, it's not about pattern matching elimination, since this definition
data Pair (A B : Set₁) : Set₁
where pair : A -> B -> Pair A B
fst : ∀ {A B} -> Pair A B -> A
fst (pair x y) = x
⟦_⟧₃ : F → Pair Set Set → Set
⟦ X ⟧₃ p = fst p
data μ₃ (f : F) : Set where
Fix₃ : ⟦ f ⟧₃ (pair (μ₃ f) ⊤) → μ₃ f
is rejected too.
Upvotes: 2