Zulip Chat Archive

Stream: Is there code for X?

Topic: Dependent typed power


Alfredo Moreira-Rosa (Sep 06 2025 at 16:48):

So for my dimensional analysis library, i needed dependent typed powers, indeed, the dimension of quantity kg^2 is Mass^2 and has type Quantity Mass^2 Real.

So using Typeclasses does not not allow to have a generic dependant power function.

I created a new notation with a custom elaborator, i share it here in case it can be of some help :

/--
Dependent power operator, allows to have the output type depend on the exponent.
`q ^ᵈ n`:
- if `n : ℕ` uses `q.npow`
- if `n : ℤ` uses `q.zpow`
- if `n : ℚ` uses `q.qpow`

Examples:
- `q ^ᵈ 2`          -- npow
- `q ^ᵈ (-2 : ℤ)`   -- zpow
- `q ^ᵈ (1/3 : ℚ)`  -- qpow
-/
syntax:80 (name := dependentPow) term:80 " ^ᵈ " term:81 : term

elab_rules : term
  | `($q:term ^ᵈ $n:term) => do
      let ne  elabTerm n none
      let nty  whnf ( inferType ne)

      let makeDot (field : Name) : TermElabM (Expr) := do
        let stx  `(($q).$(mkIdent field) $n)
        elabTerm stx none

      match nty with
      | .const ``Nat _ => makeDot `npow
      | .const ``Int _ => makeDot `zpow
      | .const ``Rat _ => makeDot `qpow
      | _ => throwErrorAt n m!"exponent must be ℕ, ℤ, or ℚ; got type {nty}"

and here an exemple of defined power instances for Nat, Int and Rat :

def npow [Pow α ] (q : Quantity d α) (n : ) : Quantity (nd) α :=
    { val := q.val ^ n }

def zpow [Pow α ] (q : Quantity d α) (n : ) : Quantity (nd) α :=
    { val := q.val ^ n }

def qpow [Pow α ] [SMul  δ] (q : Quantity d α) (n : ) : Quantity (nd) α :=
    { val := q.val ^ n }

Notification Bot (Sep 06 2025 at 17:00):

This topic was moved here from #Is there code for X? > Dependant type power by ecyrbe.

Eric Wieser (Sep 06 2025 at 17:38):

A custom elaborator is probably unnecessary here, you could just create a DPow typeclass for dependent powers

Eric Wieser (Sep 06 2025 at 17:39):

(there are previous threads which do this)

Alfredo Moreira-Rosa (Sep 06 2025 at 19:07):

i did not find any, any pointers ?

Alfredo Moreira-Rosa (Sep 06 2025 at 19:31):

By the way, i tried something like this, and it did not work as i wanted and required extra work in proofs (because Out n is not reduced).

class DPow (α : Type u) (γ : Type v) where
  Out : γ  Type w
  pow : (q : α)  (n : γ)  Out n


infix:80 (priority := high) " ^ᵈ " => DPow.pow

Alfredo Moreira-Rosa (Sep 06 2025 at 19:34):

With the elaborator solution, everything was as if i wrote q.npow manually, not the case with typeclasses

Eric Wieser (Sep 06 2025 at 22:03):

You're looking for

class DPow (α : Type u) (γ : Type v) (Out : outParam (γ  Type w_)) where
  pow : (q : α)  (n : γ)  Out n


infix:80 (priority := high) " ^ᵈ " => DPow.pow

i think

Eric Wieser (Sep 06 2025 at 22:05):

ecyrbe said:

i did not find any, any pointers ?

#new members > Type classes and dependent types @ 💬

Alfredo Moreira-Rosa (Sep 06 2025 at 22:35):

i always forget about outParam... thanks


Last updated: Dec 20 2025 at 21:32 UTC