2014-09-23 55 views
2

考慮:如何將(Vector v a)約束添加到實例聲明?

newtype Matrix (w :: Nat) (h :: Nat) v a where 
    Matrix :: v a -> Matrix w h v a 

(其中VA爲Data.Vector.Generic.Vector v a,你怎麼說?)

和:

instance Foldable (Matrix w h v) where 
    foldMap = foldMapTree 

foldMapTree :: (Vector v a, Monoid m) => (a -> m) -> Matrix w h v a -> m 

GHC抱怨:

Matrix.hs:55:15: 
    Could not deduce (Vector v a) arising from a use of ‘foldMapTree’ 
    from the context (Monoid m) 

更改爲:

instance Vector v a => Foldable (Matrix w h v) where 
    foldMap = foldMapTree 

給出:

Matrix.hs:54:10: 
    Variable ‘a’ occurs more often than in the instance head 
     in the constraint: Vector v a 
     (Use UndecidableInstances to permit this) 

使用UndecidableInstances,因爲它打破了幾乎一切並沒有多大幫助......有可能是一個簡單的解決這個問題......其他答案建議UndecidableInstances不是「壞「本身。但顯然我無法得到這個工作...

+2

添加'UndecidableInstances'不應該破壞現有的代碼,它只允許更多的程序。 – augustss 2014-09-23 08:59:07

+1

您無法將'Matrix nm'作爲'Functor'的實例,原因與您無法[[Set]]相同(https://stackoverflow.com/questions/19177125/sets-functors-and-eq混淆)或[排序二叉樹](https://stackoverflow.com/questions/20296936/is-it-possible-to-create-a-functor-instance-for-sorted-binary-trees-in-haskell) 「Functor」的一個實例。 – user2407038 2014-09-23 09:42:34

+0

您有使用'Data.Vector.Generic'的特殊原因嗎?如果你將自己限制在'Data.Vector'中,我認爲它會簡單得多。 – 2014-09-23 09:55:32

回答

2

正如在評論中指出的,你想要的是不可能的。 Foldable類表達了這樣的想法:對於給定類型的構造函數,在你的情況下,你可以爲任何參數類型a做某些事情。

但是,您的foldMapTree僅適用於有限範圍的類型,即那些存在Vector v a實例的範圍。

即使你有你的instance Vector v a => Foldable (Matrix w h v)過去的類型檢查,它不會幫助,因爲它不會表達,你需要Vector v a持有所有可能a類型的,不只是一個特定的想法。

+0

像我回答user2407038上面:GHC可以派生'Foldable'實例就好(使用'GeneralizedNewtypeDivingiving',即使用'Vector'的'Foldable'實例。我想應該可以做同樣的事情嗎? – fho 2014-09-23 13:38:56

+0

如果你可以在沒有'Vector'約束的情況下編寫'foldMapTree'實現,那就沒問題了。 – 2014-09-23 17:38:52

+0

[反過來說,如果你不能,原因就是你想要的實例不是可能] – 2014-09-23 18:08:57