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 (n•d) α :=
{ val := q.val ^ n }
def zpow [Pow α ℤ] (q : Quantity d α) (n : ℤ) : Quantity (n•d) α :=
{ val := q.val ^ n }
def qpow [Pow α ℚ] [SMul ℚ δ] (q : Quantity d α) (n : ℚ) : Quantity (n•d) α :=
{ 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 ?
Alfredo Moreira-Rosa (Sep 06 2025 at 22:35):
i always forget about outParam... thanks
Last updated: Dec 20 2025 at 21:32 UTC