如何为 double a Semigroup 制作容器?

How do I make a container for a double a Semigroup?

我正在学习Haskell。假设我有以下内容:

data Coordinate = Coordinate double

我希望为 Coordinate 实现一个半群实例。

instance Semigroup (Coordinate a) where
  Coordinate a <> Coordinate b   =  Coordinate (a+b)

类型检查器对我很不满意:

    • Expected kind ‘* -> *’, but ‘Coordinate’ has kind ‘*’
    • In the first argument of ‘Semigroup’, namely ‘(Coordinate a)’
      In the instance declaration for ‘Semigroup (Coordinate a)’
    |
175 | instance (Num a) => Semigroup (Coordinate a) where

(我知道这只是一个双人的空容器,我已经可以只使用双人本身了,但我正在学习 Haskell,我想了解它是如何工作的。)

您指定的方式 Coordinate,它没有任何类型参数。所以半群实例头应该是简单的

instance Semigroup Coordinate where
  ...

或者,您可以给它一个参数以允许包含不同的数字类型:

newtype Coordinate' a = Coordinate' { getCoordinate' :: a }

在这种情况下,Semigroup 实例 需要提及参数,但是仅调用它 a 是不够的,因为您可以' 对任意类型执行 +。您需要将其限制为 Double 那里

instance Semigroup (Coordinate' Double)

或任意数值类型

instance Num a => Semigroup (Coordinate' a)

请注意,在任何一种情况下,Semigroup 可能都不是最好的 class,请考虑使用 AdditiveGroup and then you can also make it a VectorSpace