kar*_*oss 4 haskell operator-overloading typeclass
请考虑以下示例:
data Dot = Dot Double Double
data Vector = Vector Double Double
Run Code Online (Sandbox Code Playgroud)
首先,我想重载+运算符Vector.如果我想重载equality(==)运算符,我会写它像:
instance Eq Vector where ...blahblahblah
Run Code Online (Sandbox Code Playgroud)
但我无法找到是否有Add类型类使Vector行为类似于带有加法运算的类型.我甚至找不到Haskell类型类的完整列表,我只知道很少来自不同的教程.这样的清单是否存在?
另外,我可以重载+运营商添加Vector到Dot(它似乎相当合理的,不是吗?).
Bor*_*ris 13
发现函数属于哪个类型类(如果有)的信息的简单方法是使用GHCi:
Prelude> :i (+)
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
...
-- Defined in GHC.Num
infixl 6 +
Run Code Online (Sandbox Code Playgroud)
Prelude中的operator +由类型类Num定义.但是顾名思义,这不仅定义了加法,还定义了许多其他数值运算(特别是其他算术运算符以及使用数字文字的能力),因此这不适合您的用例.
除非你想要隐藏Prelude的+运算符(这意味着你必须为Integer,Double等创建自己的Addable实例,如果你仍然希望能够在数字上使用+),就没有办法只为你的类型重载+ ).
您可以为向量加法(以及其他有意义的运算符)写入instance Num Vector重载+.
instance Num Vector where
(Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)
-- and so on
Run Code Online (Sandbox Code Playgroud)
但是,请注意+具有类型Num a => a -> a -> a,即两个操作数和结果都必须是相同的类型.这意味着你不能有一个Dot加一个Vector是一个Dot.
虽然你可以隐藏Num在Prelude并指定自己的+,这很容易造成混乱,使其难以与常规的算术一起使用你的代码.
我建议您为矢量点添加定义自己的运算符,例如
(Dot x y) `offsetBy` (Vector dx dy) = Dot (x + dx) (y + dy)
Run Code Online (Sandbox Code Playgroud)
或者如果你喜欢更短的东西,可以使用符号.