The main advantage, IMO, of a single v
in the signature is that this can then always be infered from any one of the arguments. With the more polymorphic approach, you'd end up having to write awkward explicit type signatures for intermediate expressions (probably necessiating -XScopedTypeVariables
when typically the choice would be just "use the same Vector
flavour as for the other argument" (which is probably the best choice performance-wise, and just the obvious one). Often it simply won't matter much, then it's nice not to have to worry about type signatures at all. OTOH, if you need to combine different Vector
instances, the precise type being fixed elsewhere, it's a trivial matter of throwing in GV.convert
before one of the arguments to get to the more polymorphic version. Much easier that making it less polymorphic, somewhat surprisingly.
Any reasons to restrict vector functions to one instance?
Question
Following my previous question about Data.Vector.Generic.Vector
instances I began to wonder, why
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))
and not
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))
?
Second one compiles just fine. Are there any particular reasons to restrict all such function to one instance? Because for me
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
looks WAY more 'generic'.
La solution
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow