如何声明这个函数的类型?

时间:2013-08-09 06:50:09

标签: haskell ghc

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

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}

使用XFlexibleContexts ghc接受类型声明,但在cs varibale附近抱怨

Could not deduce (v ~ Vector)

我有

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

不要真的得到,问题是什么。

1 个答案:

答案 0 :(得分:4)

这正是GHC所说的:setCharges签名只要求v Data.Vector.Generic.Vector的某个实例。 nodes,OTOH的Network字段始终是一种特定类型,即Data.Vector.Vector,这肯定是Vector类的一个实例,但可以有其他类型好。所以你不能只用其他类型替换这个字段,无论它是否是GV.Vector的实例。但是在这些实例之间有convert的通用函数,使用它并且你会没事的:

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
                       , ...
                       }

但它通常被认为是一种反模式,至少如果没有特别的理由去这条路线。