idris-lang / Idris2

A purely functional programming language with first class types
https://idris-lang.org/
Other
2.53k stars 378 forks source link

2 + 3 is not convertible to 3 + 2 #2201

Open AndrasKovacs opened 2 years ago

AndrasKovacs commented 2 years ago

Using Church-coded natural numbers, 2 + 3 = 3 + 2 is not provable:

CNat : Type
CNat = (n : Type) -> (n -> n) -> n -> n

CAdd : CNat -> CNat -> CNat
CAdd a b n s z = a n s (b n s z)

N3 : CNat
N3 n s z = s (s (s z))

N2 : CNat
N2 n s z = s (s z)

Fail : CAdd N2 N3 = CAdd N3 N2
Fail = Refl

I get "can't solve constraint between N3 and N2", using Idris2 0.5.1.

Russoul commented 2 years ago

That works xD:

CNat : Type
CNat = (n : Type) -> (n -> n) -> n -> n

CAdd : CNat -> CNat -> CNat
CAdd = \a, b, n, s, z => a n s (b n s z)

N3 : CNat
N3 = \n, s, z => s (s (s z))

N2 : CNat
N2 = \n, s, z => s (s z)

Fail : CAdd N2 N3 = CAdd N3 N2
Fail = Refl

Seemingly, It doesn't unfold the definitions.

gallais commented 2 years ago

You only need CAdd a b = \n, s, z => a n s (b n s z). That'll be because we don't eta-expand in a type-directed manner when comparing stuck neutrals (under-applied definitions are considered stuck).

AndrasKovacs commented 2 years ago

Thanks. I would consider this beta-reduction though, not eta-expansion. It's kind of weird that the arity of a top-level function is a primitive notion on the level of conversion checking.

gallais commented 2 years ago

I think that Agda, Haskell, OCaml, etc. all make a semantic distinction between f xs = \ ys => ... and f xs ys = .... You don't notice it in Agda because things get eta-expanded enough that the definition will reduce.

ice1000 commented 2 years ago

I think that Agda, Haskell, OCaml, etc. all make a semantic distinction between f xs = \ ys => ... and f xs ys = .... You don't notice it in Agda because things get eta-expanded enough that the definition will reduce.

Aya and Arend also do this 🤔. What are the benefits? My understanding is that it guarantees the number of arguments supplied for unfold

cartazio commented 2 years ago

in the context of ghc, it has to do with providing an efficient machine calling convention for known arity functions