1

我正在使用向量库并尝试编写简单的函数:

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}

使用XFlexibleContextsghc 接受类型声明,但在csvaribale附近抱怨

Could not deduce (v ~ Vector)

我有

nodes n :: Data.Vector.Vector Node
setCharge :: Node -> Double -> Node

实在搞不明白,有什么问题。

4

1 回答 1

4

这正是 GHC 所说的:setCharges签名只需要classv的某个实例。OTOH的字段始终是一种特定类型,即,它确实是该类的一个实例,但也可以有其他类型。所以你不能只用其他类型替换这个字段,不管它是否是一个实例。但是在这些实例之间有一个通用函数,使用它就可以了: Data.Vector.Generic.VectornodesNetworkData.Vector.VectorVectorGV.Vectorconvert

setCharges n cs = n{nodes = GV.zipWith setCharge (nodes n) (GV.convert cs)}

或者,您可以设计Network记录,使该nodes字段实际上是多态的,即可以保存类的任意实例而不是一种特定类型。这被称为存在主义

{-# LANGUAGE ExistentialQuantification       #-}

data Network = Network { ...
                       , nodes :: forall v . GV.Vector v => v Double
                       , ...
                       }

但它通常被认为有点反模式,至少如果没有特别的理由走这条路。

于 2013-08-09T07:21:57.487 回答