有没有办法进一步约束现有类型类的上下文?
例如,类型类Functor
:
class Functor f where
fmap :: (a -> b) -> f a -> f b
此类定义不会强制a
或b
成为Show
的元素。此类型类也是我自己包含的类,因此我无法影响类定义。是否仍然可以,以后只允许a
和b
成为Show
的成员?
答案 0 :(得分:11)
不直接。如果不更改源和重新编译,则无法更改类的定义。对于标准库中定义的类,这会导致代码严重破坏,因此不是一个现实的选择。
但是,您可以打包该类并添加所需的约束,
class Functor f => ShowFunctor f where
smap :: (Show a, Show b) => (a -> b) -> f a -> f b
smap f = fmap f
然后使用该类而不是原始类。
但也许您不需要额外的课程,对于您的应用程序,只需在顶层定义smap
就可以了,只需使用它而不是fmap
,
smap :: (Functor f, Show a, Show b) => (a -> b) -> f a -> f b
smap = fmap
答案 1 :(得分:2)
你不能在不破坏事物的情况下这样做(目前)。
你有几个选择
Functor
类实际上,我们现在知道如何允许实例添加约束,所以也许有一天这不会那么糟糕,请参阅Subcategories in Haskell以获得几乎完全解决此问题的论文。该论文中的语法与目前在GHC中的作用略有不同,但基本上我们想重新定义Functor
类看起来像
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