Skip to content

Typeable can leak information about instances defined using DerivingVia

{-# LANGUAGE GADTs #-}
{-# LANGUAGE DerivingVia #-}
module TypeableVia where

import Data.Typeable

data Typed where
  Typed :: Typeable a => a -> Typed

class C a where
  foo :: a -> Typed

newtype T a = T a

instance Typeable a => C (T a) where
  foo = Typed

newtype Foo = Foo Int
  deriving C via T Int

bar :: C a => a -> TypeRep
bar x = case foo x of
  Typed t -> typeOf t

-- bar (Foo 1) == T Int

newtype Foo' = Foo' Int

instance C Foo' where
  foo = Typed

-- bar (Foo' 1) == Foo'

At first glance, the instances for C Foo and C Foo' seem like they should be identical, but they are in fact quite distinct.

I'm not sure what exactly can be done about this.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information