I want to be able to write something like:
reify (Proxy @True)) == True;
reify (Proxy @(Just 5)) == Just 5;
Is it possible by a blanket implementation? I got as far as
class Reify (a :: k) where
reify :: Proxy a -> k
And I have no idea how to write this except than writing every instance by hand: one instance for True, one instance for False, etc. I don't want to write it all by hand, and I don't want to use template haskell to do it for me. Can I have just one instance to do it?
Or maybe there exists some other approach? The use-case for me is to be able to write:
type DeriveHelper :: Settings -> Type -> Type
newtype DeriveHelper s a = DeriveHelper a
instance (Generic a, GMyClass (Rep a)) => MyClass (DeriveHelper s a) where
myMethod (DeriveHelper x) = genericMyMethod (reify (Proxy @s)) $ from x
-- and then
data FooBar ...
deriving MyClass via DeriveHelper SomeSettings FooBar
As for the libraries I've seen in the world that do this, they seem to all have small Settings which I believe is reified by hand.
I would be remiss if I didn't note that the best solution at the moment is still the
singletonspackage, which provides thedemotefunction to do what you want (see example at the end). However, that implementation uses Template Haskell internally to lift existingPreludetypes and requires you to use TH explicitly to lift additional types. And, you said you didn't want to do that...So, I guess it's technically possible with generics. You can use
Data.TypeableorType.Reflectionto destruct the type-leveltof kindk, and then construct a termtof typekusingGHC.Generics(orData.Dataor whatever).Consider the following proof of concept which uses
Data.Typeablefor type destruction andData.Datafor term construction:This is only a partial implementation, but it will demote arbitrary nullary prefix constructors:
I don't see any technical barrier to generalizing it to handling constructors of arbitrary arity and adding support for
Int#, etc.Maybe someone's implemented this in a package somewhere, but I don't know where.
Anyway, the
singletonssolution using TH is ready-to-run and would look something like: