It's possible to derive Storable
via GHC's generic deriving mechanism: http://hackage.haskell.org/package/derive-storable (and https://hackage.haskell.org/package/derive-storable-plugin for performance). The only library I can find for deriving Data.Vector.Unbox
, however, uses template Haskell: http://hackage.haskell.org/package/vector-th-unbox. It also requires the user to write a little code; it's not entirely automatic.
My question is, could a library like deriving-storable
also exist for Unbox
, or is this not possible due to some fundamental way in which Unbox
differs from Storable
? If the latter, does that mean it's also not possible to create a library that allows automatically deriving Unbox
for any Storable
type, as I could not find such a library.
I ask because ideally I'd like to avoid template Haskell and the manual annotations necessary for using vector-th-unbox
.
Say we had some
Generic_
class to convert between our own types and some uniform representation which happens to have anUnbox
instance (which amounts to bothMVector
andVector
instances for theUnboxed
variants):Then we can use that to obtain generic implementations of the methods of
MVector
/Vector
:Now if we have some generic type
We can define a generic instance with its isomorphism to a tuple
And from there, there is a totally generic recipe to get its
Unbox
instance, if you haveYourType
instead with its ownGeneric_
instance, you can take this and literally replaceMyType
withYourType
.In theory all this boilerplate could be automated with internal language features (as opposed to TemplateHaskell or CPP). But there are various issues that get in the way in the current state of things.
First,
Generic_
is essentiallyGeneric
fromGHC.Generics
. However, the uniform representation that gets derived by GHC is not in terms of tuples(,)
but in terms of somewhat ad-hoc type constructors (:+:
,:*:
,M1
, etc.), which lackUnbox
instances.Unbox
instances could be added to useGeneric
directlyGeneric
relying on tuples that could be a direct replacement toGeneric_
here.And second,
MVector
andVector
have quite a few methods. To avoid having to list them all, one might expect to leverageDerivingVia
(orGeneralizedNewtypeDeriving
), however they are not applicable because there are a couple of polymorphic monadic methods that prevent coercions (e.g.,basicUnsafeNew
). For now, the easiest way I can think of to abstract this is a CPP macro. In fact the vector package uses that technique internally, and it might be reusable somehow. I believe properly addressing those issues requires a deep redesign of the Vector/MVector architecture.Gist (not complete, but compilable): https://gist.github.com/Lysxia/c7bdcbba548ee019bf6b3f1e388bd660