Zulip Chat Archive

Stream: lean4

Topic: Cast doesn't assign type


Pavel Klimov (Sep 24 2025 at 09:21):

The following code doesn't work

inductive Ty
| int
| str

def Ty.toType : Ty  Type
| .int => Int
| .str => String

structure TypedVal where
type : Ty
value : type.toType

def TypedValue.checkEqualToInt : TypedVal  Int  Bool
|  .int, val , int => (val : Int) == int
| _, _ => false

It works in this way, no proof required:

def TypedValue.checkEqualToInt : TypedVal  Int  Bool
|  .int, val , int =>
  let val' : Int := val
  val' == int
| _, _ => false

And, it also works in this way

def TypedValue.checkEqualToInt : TypedVal  Int  Bool
|  .int, val , int => (cast rfl val : Int) == int
| _, _ => false

Why (val : Int) doesn't work? :thinking: While temporary additional variable works.

Kenny Lau (Sep 24 2025 at 11:36):

@Pavel Klimov if you look at the error message (very useful to do in general), it says "failed to synthesize BEq Ty.int.toType", which means it failed to look beyond Ty.int.toType and see it as Int.

This is because you used def Ty.toType, which means "do not unfold me when you synthesize classes".

If you do want to unfold it automatically, you can change it to abbrev Ty.toType, and then the code you posted succeeds without error.

Robin Arnez (Sep 24 2025 at 12:35):

(val : Int) is only a hint while elaborating val, when it looks at val == int, it still sees val : Ty.int.toType. You can do show Int from val which is not only a hint for elaborating val but actually encodes the type in the resulting expression as (have : Int := val; this)


Last updated: Dec 20 2025 at 21:32 UTC