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