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