我想知道是否有可能编写一个Haskell添加运算符,它可以处理两个数字,两个数字列表,两个数字矩阵,......等等.也就是说,是否可以定义<+>
以下所有内容?:
1 <+> 2 = 3 [1] <+> [2] = [3] [[1]] <+> [[2]] = [[3]] ...
我知道,在Haskell中添加列表的惯用方法是什么?,我们可以做+
的a
,zipWith (+)
对[a]
.可能zipWith (zipWith (+))
是[[a]]
沿着同一条线,等等......
但是可以使用一个运算符(如Matlab所能)使用类型类或Haskell的其他功能来完成吗?
我知道这是合成糖,但如果可能,它会很甜.
- 更新 -
我看到使用(Num a)
@ DanielWagner的答案中所解释的可能是有问题的,并且最好Integer, Double
为基本情况单独定义它等.
仅仅是为了记录,我只是按照建议尝试:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-} class Additive a where (<+>) :: a -> a -> a instance Num a => Additive a where (<+>) = (+) instance Additive a => Additive [a] where (<+>) = zipWith (<+>)
要么
{-# LANGUAGE DefaultSignatures #-} class Additive a where (<+>) :: a -> a -> a default (<+>) :: Num a => a -> a -> a (<+>) = (+)
在任何一种情况下,加载.hs
文件或评估时都会出错[[1,2]] <+> [[3,4]]
.
是的,这是可能的:
class Additive a where (<+>) :: a -> a -> a instance Additive Integer where (<+>) = (+) instance Additive a => Additive [a] where (<+>) = zipWith (<+>)
您在ghci中的三个测试用例:
*Main> 1 <+> 2 3 *Main> [1] <+> [2] [3] *Main> [[1]] <+> [[2]] [[3]]
如果您需要大量实例(<+>) = (+)
,可以将其作为默认实现DefaultSignatures
:
{-# LANGUAGE DefaultSignatures #-} class Additive a where (<+>) :: a -> a -> a default (<+>) :: Num a => a -> a -> a (<+>) = (+)
优点是某些情况可能非常短,例如
instance Additive Integer instance Additive Int instance Additive Double instance Additive Float
将全部按预期工作,无需任何其他方法定义.