问题
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