制作Eq的VectorSpace.Scalar实例

wor*_*shi 1 haskell type-families

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

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

data Particle v = Particle { 
                         _pos   :: Point v
                       , _vel   :: v
                       , _force :: v
                       , _mass :: Scalar v
                       }
    deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*ood 5

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

instance (Show v, Show (Point v), Show (Scalar v)) => Show (Particle v) where
Run Code Online (Sandbox Code Playgroud)

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

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

deriving instance (Show v, Show (Point v), Show (Scalar v)) => Show (Particle v)
Run Code Online (Sandbox Code Playgroud)

这是GHC用户指南中描述的"独立派生声明" ,其目的基本上是为了我们可以指定GHC通常无法解决的上下文.

应该这样做.我有点担心UndecidableInstances,因为它确实看起来像它应该是能够确定的情况下Point,并Scalar使得这种情况下是圆形的,但尽管我尽了最大努力我一直没能做出typechecker循环,所以它可能很好.