I've been trying to figure out how to implement Show
for my Tensor
type for ages. Tensor
is a thin wrapper round either a single value, or arbitrarily-nested Vect
s of values
import Data.Vect
Shape : Nat -> Type
Shape rank = Vect rank Nat
array_type: (shape: Shape rank) -> (dtype: Type) -> Type
array_type [] dtype = dtype
array_type (d :: ds) dtype = Vect d (array_type ds dtype)
data Tensor : (shape: Shape rank) -> (dtype: Type) -> Type where
MkTensor : array_type shape dtype -> Tensor shape dtype
Show dtype => Show (Tensor shape dtype) where
show (MkTensor x) = show x
I get
When checking right hand side of Prelude.Show.Main.Tensor shape dtype implementation of Prelude.Show.Show, method show with expected type
String
Can't find implementation for Show (array_type shape dtype)
which is understandable given array_type
's not trivial. I believe that it should be show
able, as I can show
highly-nested Vect
s in the REPL as long their elements are Show
. I guess Idris just doesn't know it's an arbitrarily nested Vect
.
If I pull in some implicit parameters and case split on rank/shape, I get somewhere
Show dtype => Show (Tensor {rank} shape dtype) where
show {rank = Z} {shape = []} (MkTensor x) = show x -- works
show {rank = (S Z)} {shape = (d :: [])} (MkTensor x) = show x -- works
show {rank = (S k)} {shape = (d :: ds)} (MkTensor x) = show x -- doesn't work
and I can indefinitely expand this to higher and higher rank explicitly, where the RHS is always just show x
, but I can't figure out how to get this to type check for all ranks. I'd guess some recursive thing is required.
EDIT to be clear, I want to know how to do this by using Idris' implementation of Show
for Vect
s. I want to avoid having to construct an implementation manually myself.