Zulip Chat Archive
Stream: new members
Topic: Coerce array to subarray at fn call site
Somo S. (May 12 2024 at 23:11):
Suppose I have a function that naturally accepts a subarray but I want it to be invocable using an array as well (i.e. so it behaves "polymophically"). How might one achieve this?
Somo S. (May 13 2024 at 14:40):
Here is my naive attempt:
instance : Coe (Array α) (Subarray α) :=
⟨Array.toSubarray⟩
def foo (_ : Subarray α) : Unit := ()
#check foo (#[-0, 1] : Subarray Int)-- WORKS
def x : Subarray Int := #[-0, 1]
#check foo x -- WORKS
-- But what I want to work is like:
#check foo #[-0, 1] -- FIXME
/-
application type mismatch
foo #[-0, 1]
argument
#[-0, 1]
has type
Array Int : Type
but is expected to have type
Subarray ?m.754 : Type
-/
-- Or:
def y : Array Int := #[-0, 1]
#check foo ↑y -- FIXME
/-
type mismatch
y
has type
Array Int : Type
but is expected to have type
Subarray ?m.1411 : Type
-/
Eric Wieser (May 13 2024 at 17:27):
foo (α := Int) #[-0, 1]
works too, but I agree this is suboptimal
Somo S. (May 13 2024 at 19:56):
thanks thats actually helpful. for some reason, i hadn't realized i could also redefine the signature of foo
so the type is expicit
Somo S. (May 13 2024 at 19:59):
indeed not optimal, but atleast it works.
Notification Bot (May 13 2024 at 20:11):
Somo S. has marked this topic as resolved.
Notification Bot (May 13 2024 at 21:15):
Eric Wieser has marked this topic as unresolved.
Eric Wieser (May 13 2024 at 21:16):
I've unresolved this; I think this is a good question, and suggests either a shortcoming in the coercion system, or a use-case for unif_hint
which is otherwise totally unused.
Somo S. (May 13 2024 at 21:17):
i guess a good candidate for RFC then?
Kim Morrison (May 15 2024 at 21:29):
Maybe you could show us some code where this would be useful? I suspect this is mostly an #xy problem, and the real solution is to want something else. :-)
Mario Carneiro (May 15 2024 at 21:33):
@Somo S. Here's an implementation of my suggestion:
class ArrayLike (σ : Type u) (α : outParam (Type v)) where
toSubarray : σ → Subarray α
instance : ArrayLike (Array α) α := ⟨Array.toSubarray⟩
instance : ArrayLike (Subarray α) α := ⟨id⟩
instance : Coe (Array α) (Subarray α) :=
⟨Array.toSubarray⟩
def foo [ArrayLike σ α] (_ : σ) : Unit := ()
def y : Array Int := #[-0, 1]
def x : Subarray Int := #[-0, 1]
#check foo (#[-0, 1] : Subarray Int)
#check foo x
#check foo #[-0, 1]
#check foo ↑y
Somo S. (May 15 2024 at 21:40):
great @Mario Carneiro .. this is actually perfect! I had tried this.. but dont yet understand when is a good time to use outParam (so i didn't include outparam) thanks for this!
Last updated: May 02 2025 at 03:31 UTC