Zulip Chat Archive
Stream: lean4
Topic: Is it possible to make this typeclass parameter implicit ?
Frederic Peschanski (Jan 16 2025 at 12:22):
I am working on a Lean4 development involving a typeclass that looks like this:
class Model (CTX) (M) where
ctx : CTX
prop : M → Prop
A Model is some type M depending on a context.
Here is an example of a context :
structure ExCtx where
param : Nat
param_Ax : param > 0
A typical "Model" is dependent on a context,
such as the following one :
structure ExModel (ctx : ExCtx) where
value : Nat
Now I can instantiate the typeclass :
instance: Model ExCtx (ExModel ctx) where
ctx := ctx
prop m := m.value < ctx.param
Since ctx
is of type ExCtx
I tried to make the typeclass parameter CTX
implicit, e.g. doing :
class Model {CTX} (M) where
...
But this doesn't work, is is always necessary to explicit the CTX paramer, e.g.
this does not work :
instance: Model (ExModel ctx) where
ctx := ctx
prop m := m.value < ctx.param
I tried several things like relying on typeclass resolution (introducing a HasContext
class), tyring to exploit an outParam
... but failed to find a simple solution.
r.z. Almi. (Jan 16 2025 at 12:56):
Frederic Peschanski said:
structure ExCtx where param : Nat
why Nat ?
Eric Wieser (Jan 16 2025 at 13:05):
Frederic Peschanski said:
A typical "Model" is dependent on a context,
Are you willing to strengthen this to "every model must be a function from the context"?
Frederic Peschanski (Jan 16 2025 at 13:25):
Eric Wieser said:
Are you willing to strengthen this to "every model must be a function from the context"?
Yes, the context could by an empty struct anyways ...
Frederic Peschanski (Jan 16 2025 at 13:27):
r. Almi. said:
why Nat ?
It's just an example, the context can be an arbitrary structure (and so is a model, except that it depends on a context)
Tomas Skrivan (Jan 16 2025 at 15:08):
Why using outParam
does not work for you? I would just mark CTX
with it. Using outParam
make CTX
implicit argument in functions Model.ctx
and Model.param
.
class Model (CTX : outParam (Type _)) (M : Type _) where
ctx : CTX
prop : M → Prop
class Model' (CTX : Type _) (M : Type _) where
ctx : CTX
prop : M → Prop
#check Model.ctx -- `CTX` is implicit argument
#check Model'.ctx -- `CTX` is NOT implicit argument
structure ExCtx where
param : Nat
param_Ax : param > 0
structure ExModel (ctx : ExCtx) where
value : Nat
instance (ctx : ExCtx) : Model ExCtx (ExModel ctx) where
ctx := ctx
prop m := m.value < ctx.param
def exModelCtx (ctx : ExCtx) := Model.ctx (ExModel ctx)
def exModelProp {ctx : ExCtx} (m : ExModel ctx) := Model.prop m
Frederic Peschanski (Jan 20 2025 at 10:30):
Tomas Skrivan said:
instance (ctx : ExCtx) : Model ExCtx (ExModel ctx) where ctx := ctx prop m := m.value < ctx.param
What I would like to avoid is the repeatition of ExCtx
in such a class instantiation,
i.e. writing the following instead :
instance (ctx : ExCtx) : Model (ExModel ctx) where
ctx := ctx
prop m := m.value < ctx.param
I can manage this with some metaprogramming but I wanted to know if there was
something possible at the typeclass level
Tomas Skrivan (Jan 20 2025 at 18:45):
Then maybe something like this?
class Model {CTX : Type _} (M : CTX → Type _) where
prop : (ctx : CTX) → M ctx → Prop
structure ExCtx where
param : Nat
param_Ax : param > 0
structure ExModel (ctx : ExCtx) where
value : Nat
instance : Model ExModel where
prop ctx m := m.value < ctx.param
def exModelProp {ctx : ExCtx} (m : ExModel ctx) := Model.prop ctx m
Tomas Skrivan (Jan 20 2025 at 18:50):
This feels wrong as this requires to show that any context ctx
and any model m
satisfied the condition Model.prop ctx m
but I do not understand your application so it might be ok.
Last updated: May 02 2025 at 03:31 UTC