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