Skip to content

Deriving Functor / Foldable / Traversable for co-pattern type

This is probably asking too much, but could GHC derive Functor, Foldable ... for this co-pattern data type?

data StreamTag :: Type -> Type -> Type where
  HeadTag :: StreamTag a a
  TailTag :: StreamTag a (Stream a)

newtype Stream a = S (forall res. StreamTag a res -> res)

instance Functor Stream where
  fmap :: (a -> a') -> (Stream a -> Stream a')
  fmap f (S stream) = S $ \case
    HeadTag ->      f (stream HeadTag)
    TailTag -> fmap f (stream TailTag)

instance Foldable Stream where
  foldMap :: Monoid m => (a -> m) -> (Stream a -> m)
  foldMap f (S stream) = f (stream HeadTag) <> foldMap f (stream TailTag)

I'm guessing it's not worth it in any case, but is it uniquely determined?

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