I want to use data families to create efficient Set views for specific data types. For all other (Ord) data types, I want to use Data.Set as an instance. The trick, I do not want to explicitly instantiate a data class with each type that I want to use in this case. Instead, I want the shared instance to span the rest of the types.
Example:
{-# LANGUAGE TypeFamilies #-} module Test where import qualified Data.Set as D class SetKey a where data Set a :: * empty :: Set a insert :: a -> Set a -> Set a member :: a -> Set a -> Bool toList :: Set a -> [a] instance SetKey Bool where data Set Bool = BoolSet Bool Bool empty = BoolSet False False insert x (BoolSet tf) = case x of True -> BoolSet True f False -> BoolSet t True member x (BoolSet tf) = case x of True -> t False -> f toList (BoolSet tf) = if t && f then [True, False] else if t then [True] else if f then [False] else []
I know the following does not work without UndecidableInstances. However, this will cause conflicts with the Bool instance for SetKey (Bool is an Ord instance)
instance (Ord a) => SetKey a where newtype Set a = Wrap { unWrap :: D.Set a } empty = Wrap . D.empty insert x = Wrap . D.insert x . unWrap member x = Wrap . D.member . unWrap toList = D.toList . unWrap
How would I decide to solve this problem? I tried to set the default values โโdirectly in the definition of a family of data families, but either I can not understand the syntax, or the functionality simply does not exist:
class SetKey a where data Set a :: * data Set a = D.Set a empty :: Set a empty = D.empty insert :: a -> Set a -> Set a insert = D.insert member :: a -> Set a -> Bool member = D.member toList :: Set a -> [a] toList = D.toList
If the code cannot work, what can I do instead? Can such a command work if Data.Set has no requirements for Ord?
source share