{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, ScopedTypeVariables, FlexibleInstances #-} module Data.Suitable (Suitable(..), Constraints(..), withResConstraints, withConstraintsOf) where import Data.Set data family Constraints (m :: * -> *) :: * -> * class Suitable m a where constraints :: Constraints m a withResConstraints :: Suitable m a => (Constraints m a -> m a) -> m a withResConstraints f = f constraints withConstraintsOf :: Suitable m a => m a -> (Constraints m a -> k) -> k withConstraintsOf _ f = f constraints data instance Constraints ((->) r) a = FuncConstraints instance Suitable ((->) r) a where constraints = FuncConstraints data instance Constraints Maybe a = MaybeConstraints instance Suitable Maybe a where constraints = MaybeConstraints data instance Constraints [] a = ListConstraints instance Suitable [] a where constraints = ListConstraints data instance Constraints IO a = IOConstraints instance Suitable IO a where constraints = IOConstraints data instance Constraints Set a = Ord a => SetConstraints instance Ord a => Suitable Set a where constraints = SetConstraints