1

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

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

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

标量不在 Eq 或 Show 中!所以这不会编译。不过,质量应该是与其他向量“兼容”的标量。我该如何调和呢?我对类型族的理解不足以分析这种情况。我试过了,但它们很难掌握。不确定是否需要或可能将标量添加到 Eq。

4

1 回答 1

5

如果你想显示质量场,显示实例必须看起来像

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)

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

这应该可以解决问题。我有点担心 UndecidableInstances,因为它似乎应该可以定义的实例PointScalar这样的实例是循环的,但是尽管我尽了最大的努力,我还是无法使类型检查器循环,所以可能没问题。

于 2012-06-07T17:34:21.360 回答