$(singletons [d|
data Nat = Z | S Nat
data Vec n a where
VNil :: Vec 'Z a
(:::) :: a -> Vec n a -> Vec ('S n) a
|])
I frequently find myself wanting to singletonize functions that already use singletons, but since singletons can't do that I have to write it by hand. E.g., consider the vector version of replicate:
vReplicate :: SNat n -> a -> Vec n a
vReplicate SZ _ = VNil
vReplicate (SS n) x = x ::: vReplicate n x
It'd be nice if wrapping that in $(singletons [d| ... |]) automatically generated:
type family VReplicate (n :: Nat) (x :: a) :: Vec n a where
VReplicate 'Z _ = 'VNil
VReplicate ('S n) x = x '::: VReplicate n x
sVReplicate :: SNat n -> Sing (x :: a) -> SVec (VReplicate n x)
sVReplicate SZ _ = SVNil
sVReplicate (SS n) x = x :%:: sVReplicate n x
As well as all the defunctionalization symbols and whatnot.
Instead, it tries to generate things like sVReplicate :: Sing (n' :: SNat n) -> ...; as far as I'm aware, meta-singleton types like that are never actually useful.
I guess one problem would be in telling whether or not a type is a singleton, so you know when to prepend an S; would you need to add a typeclass to store the relationship between a type and its singleton type or something?
(My apologies if this idea doesn't generalize to more advanced stuff; I've only tried it on simple things like vReplicate, and so far there's always been a unique obvious way to singletonize everything manually.)
I frequently find myself wanting to singletonize functions that already use singletons, but since
singletonscan't do that I have to write it by hand. E.g., consider the vector version ofreplicate:It'd be nice if wrapping that in
$(singletons [d| ... |])automatically generated:As well as all the defunctionalization symbols and whatnot.
Instead, it tries to generate things like
sVReplicate :: Sing (n' :: SNat n) -> ...; as far as I'm aware, meta-singleton types like that are never actually useful.I guess one problem would be in telling whether or not a type is a singleton, so you know when to prepend an
S; would you need to add a typeclass to store the relationship between a type and its singleton type or something?(My apologies if this idea doesn't generalize to more advanced stuff; I've only tried it on simple things like
vReplicate, and so far there's always been a unique obvious way to singletonize everything manually.)