2

在我之前关于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 

看起来更“通用”。

4

1 回答 1

2

IMO 签名中单个的主要优点v是,它总是可以从任何一个参数中推断出来。使用更多的多态方法,您最终不得不为中间表达式编写笨拙的显式类型签名(-XScopedTypeVariables当通常选择只是“使用与Vector其他参数相同的风格”时可能需要)(这可能是最好的选择性能-明智的,只是显而易见的)。通常它根本无关紧要,那么完全不必担心类型签名是很好的。OTOH,如果你需要组合不同Vector的实例,精确的类型在其他地方固定,投入是一件小事GV.convert在获得更多多态版本的参数之一之前。让它不那么多态更容易,有点令人惊讶。

于 2013-08-10T08:59:28.217 回答