Natural `CallStack` support for `Annotation`
parsonsmatt opened this issue · 1 comments
The type AnnC
is a constraint alias for Eq a, Show a, Typeable a
.
The functionality of the library absolutely depends on Typeable a
, but without anything else, then Annotation
is "just" a Data.Dynamic.Dynamic
value.
One of the most obviously useful types to have in there is CallStack
, which we cannot put in a [Annotation]
because it lacks a Show
instance. I've filed a GHC issue requesting one, but it will be a while before that is resolved.
One possibility is to write special support for CallStack
in castAnnotation
that, if you're trying to cast out a CallStack
, we look for a CallStackAnnotation
instead. This is a bit gross but it completely solves the problem . . if you're using castAnnotation
instead of cast
directly on the underlying value.
Maybe what's really necessary here is to use an Exception
-like subtyping hierarchy with a custom class for doing the conversion. Annotation
is already morally equivalent to SomeException
in that an Exception e
is just a (Show a, Typeable a)
value. Having toAnnotation
and fromAnnotation
as the main methods on the class would provide a neat entry point to this. Then we have:
class (Typeable a, Show a) => Annotation a where
toAnnotation :: a -> SomeAnnotation
fromAnnotation :: SomeAnnotation -> Maybe a
data SomeAnnotation where
SomeAnnotation :: Annotation a => a -> SomeAnnotation
This doesn't help with CallStack
because we don't have a Show
instance for it, so we still can't write instance Annotation CallStack
.
Eh, I think the easiest thing to do here is special-case on CallStack
and forward to the newtype
wrapper. That should simplify quite a lot of code. Eventually if CallStack
gets a Show
instance then we can drop all that machinery.