我对学习哈斯克尔相对较新。
我有以下抽象数据类型
data Scalar =
Scalar Integer
deriving (Eq, Show)
我希望能够在Scaler类型上执行以下操作:
> (Scalar 10) + 1
> Scalar 11
要做到这一点,我尝试将Scalar
类的num
实例设为这样:
instance Num Scalar where
(Scalar i1) + i2 = (Scalar (i1+i2))
但这不起作用。我究竟做错了什么?最新的方法是什么?
修改 我得到的错误是:
Couldn't match expected type `Integer' with actual type `Scalar ' In the second argument of `(+)', namely `i2' In the first argument of `Scalar ', namely `(i1 + i2)'
答案 0 :(得分:5)
不,你不能这样做,因为+
的类型是:
λ> :t (+)
(+) :: Num a => a -> a -> a
因此,它对相同数据的类型进行操作。在您的情况下,您尝试添加一种无效的Scalar
和Integer
类型。您可以定义这样的实例:
instance Num Scalar where
(Scalar i1) + (Scalar i2) = Scalar (i1 + i2)
它将在Scalar
类型:
λ> Scalar 3 + Scalar 4
Scalar 7
但如果您真的想这样做,可以为此创建自己的特殊功能:
addNumtoScalar :: Integer -> Scalar -> Scalar
addNumtoScalar x (Scalar y) = Scalar (x + y)
然后您可以使用此功能添加
λ> addNumtoScalar 3 (Scalar 7)
Scalar 10
或者以中缀方式:
λ> 3 `addNumtoScalar` (Scalar 7)
Scalar 10
正如@ user5402所评论的那样,您可以定义fromInteger
类型类的Num
函数,然后在添加中使用它。像这样:
instance Num Scalar where
(Scalar x) + (Scalar y) = Scalar (x + y)
fromInteger x = Scalar x
现在,您可以使用整数文字,并在必要时将它们自动转换为Scalar
值,例如:
λ> 3 + Scalar 7
Scalar 10
答案 1 :(得分:2)
您无法添加Scalar
和Integer
(例如Scalar 10 + 1
);你应该在添加之前将第二个值包装在Scalar中。因此,您的实例应如下所示:
instance Num Scalar where
(Scalar i1) + (Scalar i2) = (Scalar (i1+i2))
但是,Num
类型类提供了除+
之外还需要实现的其他几种方法。您可以使用GHC GeneralizedNewtypeDeriving扩展来处理所有这些内容,而不是手动编写所有内容:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Scalar = Scalar Integer deriving (Eq,Show,Num)
这将根据Num
实现Scalar
类型类的方式自动派生Integer
Num
个实例。这种方法要求您使用新类型,但听起来它适合您的用例。
答案 2 :(得分:1)
首先,你的定义有问题:
(Scalar i1) + i2 = (Scalar (i1+i2))
应该如下:
(Scalar i1) + (Scalar i2) = Scalar (i1+i2)
其次,如果你看一下documentation of the Num
typeclass
您将看到有关最小完整定义的部分。
(+), (*), abs, signum, fromInteger, (negate | (-))
您已经实施了(+)
,但没有实施其他任何内容。
最后,如果您发布了问题,请提供您正在获取的错误。
祝你好运答案 3 :(得分:0)
正如其他人已经指出+
两侧的类型需要匹配。您可以做的是定义自定义运算符以添加Scalar
和Int
:
(+.) :: Scalar -> Int -> Scalar
(Scalar i1) +. i2 = Scalar (i1 + i2)
infixl 6 +.
您可能还想使用newtype
包装器(您只需将data
关键字替换为newtype
)。这在语义上是相同的(除了在一些具有未定义值的极端情况下)但效率稍高,因为在编译期间会删除newtypes。