问题
I'm using vector library and trying to write simple function:
import qualified Data.Vector.Generic as GV
setCharges :: GV.Vector v Double =>
Network -> v Double -> Network
setCharges n cs = n{nodes = GV.zipWith setCharge (nodes n) cs}
With XFlexibleContexts ghc accepts type declaration but complain near cs varibale
Could not deduce (v ~ Vector)
I have
nodes n :: Data.Vector.Vector Node
setCharge :: Node -> Double -> Node
Don't really get, what the problem.
回答1:
It's just what GHC says: the setCharges signature only requires that v is some instance of the class Data.Vector.Generic.Vector. The nodes field of Network, OTOH, is always one particular type, namely Data.Vector.Vector, which sure enough is an instance of the Vector class, but there can be others as well. So you can't just replace this field with some other type, no matter if it's an instance of GV.Vector or not. But there's a generic function to convert between such instances, use that and you'll be fine:
setCharges n cs = n{nodes = GV.zipWith setCharge (nodes n) (GV.convert cs)}
Alternatively, you could design the Network record so the nodes field is in fact polymorphic, i.e. can hold arbitrary instances of the class rather than one particular type. This is called an existential:
{-# LANGUAGE ExistentialQuantification #-}
data Network = Network { ...
, nodes :: forall v . GV.Vector v => v Double
, ...
}
But it's generally considered a bit of an antipattern, at least if there isn't a particular reason to go this route.
来源:https://stackoverflow.com/questions/18141442/how-to-declare-type-of-this-function