Zulip Chat Archive

Stream: mathlib4

Topic: Coercion from Nat to Unit


Jovan Gerbscheid (Mar 15 2024 at 16:54):

I just found out that this type checks:

def foo (n : Nat) : Unit := n

Is this intended behaviour? I think it is confusing.

Jireh Loreaux (Mar 15 2024 at 16:57):

Yes, it's intended, at least if the coercion it's finding is the the same as the one mine found. It's getting a docs#NatCast instance from the docs#Semiring instance for Unit.

David Renshaw (Mar 15 2024 at 17:00):

complete example (the import is needed):

import Mathlib.Algebra.PUnitInstances

def foo (n : Nat) : Unit := n

set_option pp.all true in
#print foo
/-
def foo : Nat → Unit :=
fun (n : Nat) ↦
  @Nat.cast.{0} Unit
    (@Semiring.toNatCast.{0} Unit
      (@CommSemiring.toSemiring.{0} Unit (@CommRing.toCommSemiring.{0} Unit PUnit.commRing.{0})))
    n
-/

Jireh Loreaux (Mar 15 2024 at 17:01):

import Mathlib.Algebra.PUnitInstances is the minimal import

Jovan Gerbscheid (Mar 15 2024 at 17:03):

It seems like the constant Semiring.toNatCast doesn't have a definition anywhere.

Jireh Loreaux (Mar 15 2024 at 17:10):

It's generated by the extends keyword in the definition of docs#Semiring

Jireh Loreaux (Mar 15 2024 at 17:11):

Although it's a little nonobvious to see why

Jovan Gerbscheid (Mar 15 2024 at 17:14):

Aha, but strangely ctrl+click doesn't work on Semiring.toNatCast for me.

Jireh Loreaux (Mar 15 2024 at 17:14):

Technically, the line is:

class Semiring (α : Type u) extends NonUnitalSemiring α, NonAssocSemiring α, MonoidWithZero α

but some of these classes share fields. As a result, Lean takes a NonUnitalSemiring as the sole "true" parent, and then takes the remaining fields from NonAssocSemiring and makes them fields of the new class. But one of the non-overlapping fields of NonAssocSemiring is toNatCast

Jireh Loreaux (Mar 15 2024 at 17:16):

The same thing happens for docs#NonAssocSemiring, which is:

class NonAssocSemiring (α : Type u) extends NonUnitalNonAssocSemiring α, MulZeroOneClass α,
    AddCommMonoidWithOne α

And the same thing happens again with docs#AddCommMonoidWithOne until you get to docs#AddMonoidWithOne which has an honest-to-god docs#NatCast in its extends clause.

Jireh Loreaux (Mar 15 2024 at 17:19):

Jovan Gerbscheid said:

Aha, but strangely ctrl+click doesn't work on Semiring.toNatCast for me.

I'm not sure about the reason for this.

Jovan Gerbscheid (Mar 15 2024 at 17:20):

when viewing the definition in the online documentation, I see

class Semiring (α : Type u) extends NonUnitalSemiring , One , NatCast : Type u

Jovan Gerbscheid (Mar 15 2024 at 17:22):

Is that intended?

Jovan Gerbscheid (Mar 15 2024 at 17:29):

Would it be worth it to make the group, ring, etc. instances of Unit scoped? In general I wouldn't want anything to coerce to a Unit or PUnit.

Kyle Miller (Mar 15 2024 at 17:33):

I think it makes sense not having Unit itself be a semiring, or at least scoping it. I'd even be inclined to define def ZeroSemiring := Unit and giving this synonym the instances instead.

(I'm moving this discussion to the mathlib stream)

Notification Bot (Mar 15 2024 at 17:34):

This topic was moved here from #lean4 > Coercion from Nat to Unit by Kyle Miller.

Floris van Doorn (Mar 15 2024 at 18:15):

Kyle Miller said:

I think it makes sense not having Unit itself be a semiring, or at least scoping it. I'd even be inclined to define def ZeroSemiring := Unit and giving this synonym the instances instead.

(I'm moving this discussion to the mathlib stream)

I don't mind keeping the current state.
If we want to have a type synonym, then I think we should have a single type synonym (TrivialStructure?) that has all trivial algebraic structures, and not different synonyms for e.g. TrivialGroup and TrivialRing.


Last updated: May 02 2025 at 03:31 UTC