将矢量函数限制为一个实例的任何理由?

时间:2013-08-10 06:23:42

标签: haskell typeclass

关于我previous question关于Data.Vector.Generic.Vector个实例,我开始怀疑,为什么

zipWith :: (Vector v a, Vector v b, Vector v c)
        => (a -> b -> c) -> v a -> v b -> v c
zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))

而不是

zipWith :: (GV.Vector v1 a, GV.Vector v2 b, GV.Vector v3 c) 
        => (a -> b -> c) -> v1 a -> v2 b -> v3 c
zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))

第二个编译得很好。是否有任何特殊原因将所有此类功能限制为一个实例?因为对我来说

v1 = Data.Vector.fromList [1,2,3,4,5]
v2 = Data.Vector.Unboxed.fromList [6,7,8,9] :: Data.Vector.Unboxed.Vector Int
v3 = foo (*) v1 v2 :: Data.Vector.Unboxed.Vector Int
v4 = foo (*) v1 v2 :: Data.Vector.Vector Int 

看起来更像'通用'。

1 个答案:

答案 0 :(得分:2)

签名中单个v的主要优势IMO可以始终从任何一个参数中获取。使用更多的多态方法,您最终必须为中间表达式编写笨拙的显式类型签名(可能需要-XScopedTypeVariables,而通常选择只是“使用与其他Vector相同的Vector味道参数“(这可能是性能方面最好的选择,而且只是明显的选择)。通常它根本不会太重要,那么不必担心类型签名就好了.OTOH,如果你需要来组合不同的GV.convert实例,在其他地方修复的精确类型,在一个参数之前抛出{{1}}以获得更多的多态版本是一件小事。更容易使其不那么多态,有点令人惊讶。