如何进一步约束Haskell中的现有类型类

时间:2012-03-07 09:18:36

标签: haskell functional-programming typeclass

有没有办法进一步约束现有类型类的上下文?

例如,类型类Functor

class Functor f where
    fmap :: (a -> b) -> f a -> f b

此类定义不会强制ab成为Show的元素。此类型类也是我自己包含的类,因此我无法影响类定义。是否仍然可以,以后只允许ab成为Show的成员?

2 个答案:

答案 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)

你不能在不破坏事物的情况下这样做(目前)。

你有几个选择

  1. 定义您自己的受限Functor
  2. 不要担心定义一个类,只需定义一个能够做你想要的功能
  3. 使用RMonad package
  4. 作弊
  5. 实际上,我们现在知道如何允许实例添加约束,所以也许有一天这不会那么糟糕,请参阅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