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}

ghc は型宣言をXFlexibleContexts受け入れますが、変数の近くで文句を言いcsます

Could not deduce (v ~ Vector)

私は持っている

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

本当にわからない、何が問題なのか。

4

1 に答える 1

4

それはGHCが言っていることです:setCharges署名はそれがclassvのいくつかのインスタンスであることだけを必要とします。OTOHのフィールドは常に 1 つの特定の型、つまりであり、これは確かにクラスのインスタンスですが、他にも存在する可能性があります。したがって、インスタンスであるかどうかに関係なく、このフィールドを他のタイプに置き換えることはできません。しかし、そのようなインスタンスの間には一般的な関数があります。それを使用すれば問題ありません。 Data.Vector.Generic.VectornodesNetworkData.Vector.VectorVectorGV.Vectorconvert

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

あるいは、フィールドが実際にポリモーフィックにNetworkなるようにレコードを設計することもできますnodes。つまり、特定の 1 つのタイプではなく、クラスの任意のインスタンスを保持できます。これは実存的と呼ばれます:

{-# LANGUAGE ExistentialQuantification       #-}

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

しかし、少なくともこのルートに行く特別な理由がない限り、これは一般的に少しアンチパターンと見なされます。

于 2013-08-09T07:21:57.487 に答える