使Vector.Generic成为Functor(和其他类型类)的实例

时间:2011-10-27 16:17:16

标签: haskell typeclass

我在尝试使Vector.Generic.Vector成为其他类型类的实例(在我的情况下是Functor)时遇到了麻烦。

我可以满足于向Vector.Unboxed.Vector添加一个Functor实例,但我无法弄清楚它的语法。 我最好的尝试是尝试类似的东西:

instance (U.Unbox a, U.Unbox b) => Functor U.Vector where
    fmap = U.map

但编译器(正当地)抱怨'a'和'b'在'=>'之后无处可去。 我是否可以为Functor定义这个定义,因为它假设对fmap允许的类型有更多限制?

我在SO中发现的大多数东西都太难以让我弄清楚,所以请温柔: - )

2 个答案:

答案 0 :(得分:8)

考虑fmap的类型:

fmap :: Functor f => (a -> b) -> f a -> f b

您正尝试添加ab都是Unbox实例的约束。这是不可行的,因为fmap完全是一般的,而未装箱的Vector的地图特定于实例Unbox

不能成为Functor

答案 1 :(得分:4)

monadic是正确的,这在haskell目前是不可能的。然而,ghc head development分支中目前的新语言功能将使这成为可能。

该功能称为Constraint Kinds,并且(在其他功能中)允许您向类添加索引约束。类的实例可以决定需要什么约束。如果实例未声明一个,则可以提供默认约束。

例如,Functor类可以像这样重写:

class Functor m where
  type FunctorCtxt f a :: Constraint
  type FunctorCtxt f a = ()
  fmap :: (FunctorCtx f a, FunctorCtx f b) => f a -> f b

诸如列表和Maybe之类的现有实例将保持不变 - 给出一个默认的无关上下文(任何类型变量都是可接受的)。您可以为Vector实例添加新约束:

instance Functor U.Vector where
    type FunctorCtxt U.Vector a = U.Unbox a
    fmap = U.map

详情请见Constraint Kinds for GHC blog postKindFact GHC wiki post

请注意,我的计算机上没有安装ghc head,所以我无法测试这是否真的有效。