Zulip Chat Archive
Stream: new members
Topic: Can't figure out type universe mismatch
aron (Feb 01 2025 at 18:50):
When I define this data structure:
import Std.Data.HashSet
import Mathlib
open Std.DHashMap
instance [BEq k] [Hashable k] : Hashable (Std.HashSet k) where
hash a := Std.HashSet.toArray a |> hash
structure DependentDisjointSet {v : Type u} (k : Type u) [BEq k] [Hashable k] (valType : Std.HashSet k → v) where
innerMap : Std.DHashMap (Std.HashSet k) valType
I get this error when I set valType
as the value to Std.DHashMap
:
application type mismatch
@Std.DHashMap (Std.HashSet k) valType
argument
valType
has type
Std.HashSet k → v : Type u
but is expected to have type
Std.HashSet k → Type ?u.111 : Type (max (?u.111 + 1) u)
This doesn't happen when I set the return type of valType
to just be a plain Type u
instead of the v
declared earlier in the type signature. I don't understand what the problem is though. How can I fix this?
Kyle Miller (Feb 01 2025 at 19:07):
I'm not sure what you're going for here. The valType
function gives values of v
, but DHashMap
wants a function that gives types for each value, not values of v
.
Aaron Liu (Feb 01 2025 at 19:08):
Let's try to use your definition as-is, ignoring the type error. Your definition is
DependentDisjointSet {v : Type u} (k : Type u) [BEq k] [Hashable k] (valType : Std.HashSet k → v)
I will substitute v := Nat
, k := Bool
and valType := fun (s : Std.HashSet Bool) => s.size
. You can check that these are all type correct.
What type should innerMap
have? According to your definition, it is a Std.DHashMap (Std.HashSet Bool) fun s => s.size
.
Let's try to insert a value. According to the signature of docs#Std.DHashMap.insert, I need to provide a key of type Std.HashSet Bool
first. I'll pick {}
. Then, I need to provide a value of type (fun s => s.size) {}
, which reduces to 0
. I need to provide a value of type 0
. What does that even mean?
As you can see, I ran into a problem. Lean sees this problem in advance when type-checking your definition, and raises an application type mismatch
error.
aron (Feb 01 2025 at 19:15):
Hm so what I have in mind is for v
to be something like MyType n
, where n
is a Nat
that's derived from the key, which in this case is a Std.HashSet Bool
. So the dependent type would be more like fun s => MyType s.size
which for the empty key set would equal MyType 0
.
Does that make more sense? Or have I missed the point you're making?
Aaron Liu (Feb 01 2025 at 19:21):
What you have in mind is great, but it doesn't stop the possibility of v
being Nat
. In fact, since the parameter v
is a standalone type, it cannot depend on the key.
Aaron Liu (Feb 01 2025 at 19:25):
If you want to enforce this, do
structure DependentDisjointSet (k : Type u) [BEq k] [Hashable k] (v : Std.HashSet k → Nat) where
innerMap : Std.DHashMap (Std.HashSet k) fun s => MyType (v s)
Aaron Liu (Feb 01 2025 at 19:28):
The example I gave ran into a problem because valType
could return something that wasn't a type, which I did by making it return a Nat
. This is why the signature of docs#Std.DHashMap requires its second argument to return a Type v
.
aron (Feb 01 2025 at 19:43):
Hmm ok I don't 100% understand the issue yet, but it does make sense to me that if v
is a standalone type then it's not a dependent type.
The truth is since I don't think I need to reference v
outside of valType
, I can just make valType
have type Std.HashSet k → Type u
and that works fine
Last updated: May 02 2025 at 03:31 UTC