注意:我可能不需要将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。
答案 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,因为确实似乎应该可以定义Point
和Scalar
的实例,这样这个实例是循环的,但是尽管我付出了最大的努力,但我还是无法进行类型检查循环,所以它可能很好。