List of items of types restricted by typeclass

haskell, heterogeneous, typeclass

Solution

If I understand things correctly, there needs to be a data type wrapping the existential in order for there to be a place to store the type class dictionary along with each element.

Adding some wrappers makes it work:

{-# LANGUAGE ExistentialQuantification, TypeSynonymInstances #-}

module Test where

class Someable a where
  some :: a -> String

data Some = Some String

data SomeWrapper = forall a. Someable a => SomeWrapper a

type SomeGroup = [SomeWrapper]

instance Someable Some where
  some (Some v) = v

instance Someable SomeWrapper where
  some (SomeWrapper v) = some v

instance Someable SomeGroup where
  some (x:xs) = (some x) ++ ", " ++ (some xs)

main = do
  putStrLn $ some [SomeWrapper (Some "A"), SomeWrapper [SomeWrapper (Some "B"), SomeWrapper (Some "C")]]

Of course, this is a bit ugly. I'm not aware of any better way, unfortunately.

Problem

I'm trying to encode a list of items which have types restricted to be instances of some type class: ``` {-# LANGUAGE RankNTypes, TypeSynonymInstances, LiberalTypeSynonyms #-} module Test where class Someable a where some :: a -> String data Some = Some String type SomeGroup = forall a. Someable a => [a] instance Someable Some where some (Some v) = v instance Someable SomeGroup where some (x:xs) = (some x) ++ ", " ++ (some xs) main = do putStrLn $ show.some [Some "A", [Some "B", Some "C"]] ``` But compilation fails with error: ``` Test.hs:14:10: Illegal polymorphic or qualified type: SomeGroup In the instance declaration for `Someable SomeGroup' ``` It seems I even failed to define instance for type synonymous... I'm aware of heterogenous collections wiki article, but want to know why exactly my approach doesn't work — it seems natural to me to define type by restricting collection only to contain items with types which is instance of some type class.

Original source