Is there a way to further constrain the context of an existing type class?
For example, the type class Functor
:
class Functor f where
fmap :: (a -> b) -> f a -> f b
This class definition does not enforce a
or b
to be an element of Show
. Also this type class is a class that is included by myself, so i can't influence the classes definition. Is it still possible, to later allow only that a
's and that b
's, that are member of Show
?
Not directly. The class's definition cannot be changed without changing the source and recompiling. In the case of classes defined in the standard libraries, that would cause much breaking of code, so is not a realistic option.
You can however, wrap the class and add your desired constraints,
class Functor f => ShowFunctor f where
smap :: (Show a, Show b) => (a -> b) -> f a -> f b
smap f = fmap f
and then use that class instead of the original.
But maybe you don't need the additional class and for your applications it is sufficient to define smap
at the top level and simply use that instead of fmap
,
smap :: (Functor f, Show a, Show b) => (a -> b) -> f a -> f b
smap = fmap
You cant do that without breaking things (currently).
You have a couple of options
Functor
classActually, we now know how to allow instances to add constraints, so perhaps one day this wont be so bad, see Subcategories in Haskell for a paper that deals with almost exactly this issue. The syntax in that paper is a little different than what currently works in GHC, but basically we would like to redefine the Functor
class to look like
class Functor f where
type SubCat f :: * -> Constraint -- associated constraint
type SubCat f = () -- default definition
fmap :: (SubCat f a, SubCat f b) => (a -> b) -> f a -> f b
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With