制作Eq的VectorSpace.Scalar实例

时间:2012-06-07 16:31:39

标签: haskell type-families

注意:我可能不需要将Scalar添加到Eq中,但如果我能弄清楚如何做到这一点,它应该可以解决问题。

所以我正在尝试向ForceLayout模块添加一些功能。像粒子一样向粒子添加质量:

data Particle v = Particle { 
                         _pos   :: Point v
                       , _vel   :: v
                       , _force :: v
                       , _mass :: Scalar v
                       }
    deriving (Eq, Show)

但是Scalar不在Eq或Show中!所以这不会编译。 Mass应该是与其他向量“兼容”的标量。我该怎么调和呢?我不明白打字家庭足以分析这种情况。我已经尝试了,但他们很难掌握。不确定是否有必要或可能将标量添加到Eq。

1 个答案:

答案 0 :(得分:5)

如果要显示质量字段,show实例必须看起来像

instance (Show v, Show (Point v), Show (Scalar v)) => Show (Particle v) where

可以说,GHC不能解决这个问题是一个错误,或者至少是一个缺失的功能。幸运的是,随着一些扩展繁重,我们可以自己给它上下文:

{-# LANGUAGE StandaloneDeriving, TypeFamilies,
    FlexibleContexts, UndecidableInstances #-}
{- ... -}

deriving instance (Show v, Show (Point v), Show (Scalar v)) => Show (Particle v)

这是the GHC user guide中描述的“独立派生声明”,其目的基本上是为了我们可以指定GHC通常无法解决的上下文。

应该这样做。我有点担心UndecidableInstances,因为确实似乎应该可以定义PointScalar的实例,这样这个实例是循环的,但是尽管我付出了最大的努力,但我还是无法进行类型检查循环,所以它可能很好。