In Haskell i can define an endofunctor fixpoint so:
data Fix f = Fix (f (Fix f))
But in Agda can't:
data Fix (F : Id (Set → Set)) : Set where
fix : (unId F) (Fix F) → Fix F
as it says "Fix is not strictly positive, because it occurs in an argument to a bound variable in the type of the constructor fix in the definition of Fix."
I tried using Coinduction.∞
from the stdlib, in vain:
data Fix (F : Set → Set) : Set where
fix : ∞ (F (Fix F)) → Fix F
or
data Fix (F : Set → Set) : Set where
fix : F (∞ (Fix F)) → Fix F
neither works.
I found this doc which defines polynomial functors Functor
and a function [_] : Functor → Set → Set
which works:
data Functor : Set₁ where
Id : Functor
Const : Set → Functor
_⊕_ : Functor → Functor → Functor
_⊗_ : Functor → Functor → Functor
[_] : Functor → Set → Set
[ Id ] B = B
[ Const C ] _ = C
[ F ⊕ G ] B = [ F ] B ⊎ [ G ] B
[ F ⊗ G ] B = [ F ] B × [ G ] B
data Fix (F : Functor) : Set where
fix : [ F ] (Fix F) → Fix F
but i'm not sure why that would and this wouldn't, as both have Fix
as an argument to the bound variable F
.
Can one define a general endofunctor fixpoint in Agda, and if so, how?
EDIT: This was marked as a possible duplicate of 14699334, but the only answer there links to an (the?) Agda tutorial which includes fixpoints of a specific polynomial functor type; i want to know whether one can define this more generally. In particular, i want to define fixpoints of types which may be structurally equal but are nominally inequal.