当前位置:  开发笔记 > 开发工具 > 正文

在这个例子中有没有办法避免UndecidableInstances?

如何解决《在这个例子中有没有办法避免UndecidableInstances?》经验,为你挑选了1个好方法。

当我尝试这个:

import GHC.Generics (Generic)
import Control.DeepSeq (NFData(..))
import Data.Vector.Generic (Vector)

data Entry a = Entry !Bool a
             deriving (Generic, NFData)

-- The variable @v@ is meant to be instantiated with a 'Vector'
-- type.  Most operations for the type have a @Vector v (Entry a)@
-- constraint.
newtype DenseIntMap v a = DenseIntMap (v (Entry a))

instance NFData (v (Entry a)) => NFData (DenseIntMap v a) where
  rnf (DenseIntMap va) = rnf va

...我收到此错误:

/Users/casillas/GitHub/tau-sigma/src/TauSigma/Util/DenseIntMap.hs:53:10:
    Constraint is no smaller than the instance head
      in the constraint: Vector v (Entry a)
    (Use UndecidableInstances to permit this)
    In the instance declaration for ‘NFData (DenseIntMap v a)’

/Users/casillas/GitHub/tau-sigma/src/TauSigma/Util/DenseIntMap.hs:53:10:
    Constraint is no smaller than the instance head
      in the constraint: NFData (v (Entry a))
    (Use UndecidableInstances to permit this)
    In the instance declaration for ‘NFData (DenseIntMap v a)’

使用UndecidableInstances确实让它消失了,但我担心使用该扩展.在这种情况下,还有其他方法可以使事情发挥作用吗?(最好不要改变类型.)



1> dfeuer..:

警告:我还没有测试过这些代码.

对我来说最干净的方法是遵循一种Prelude.Extras风格的方式:

class NFData1 f where
  rnf1 :: NFData a => f a -> ()

现在,您可以为每种矢量类型编写类似的内容

instance NFData1 V where
  rnf1 = rnf

然后

instance (NFData1 v, NFData a) => NFData (DenseIntMap v a) where ...

可满足当前代码更好的替代方法是想想v作为一个Vector明确的.而不是担心如何v a更愿意强迫自己,而是通过折叠将自己的想法压在喉咙上:类似的东西

instance (Vector v a, NFData a) => NFData (DenseIntMap v a) where
  rnf = V.foldl' (\() e -> rnf e) ()

第二种方法似乎很可能在矢量融合方面表现不佳,除非你小心想要从左到右强制哪些矢量以及从右到左强制哪些矢量.

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有