我想知道是否可以编写一个Haskell add运算符,它可以处理两个数字,两个数字列表,两个数字矩阵,......等等。也就是说,是否可以定义<+>
以使以下所有方法都有效?:
1 <+> 2 = 3
[1] <+> [2] = [3]
[[1]] <+> [[2]] = [[3]]
...
我知道,就像在What is an idiomatic way to add lists in Haskell?中一样,+
a
,zipWith (+)
[a]
zipWith (zipWith (+))
。可能[[a]]
代表(Num a)
,沿同一行,依此类推......
但是可以使用一个运算符(就像Matlab那样)使用类型类或Haskell的其他功能来完成吗?
我知道这是合成糖,但如果可能的话会很甜。
- 更新 -
我发现使用Integer, Double
可能会出现问题,如@ DanielWagner的回答所述,并且可能最好为{-# 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 A {
public Return_type method1(param1, param2) {
for(var : tillSomeValue) {
try {
value = someMethod(var);
} catch (someException ex) {
/* do some calculation here with the value of thrown exception */
throw anotherException();
}
}
}
}
时都会出错。
答案 0 :(得分:5)
是的,可能:
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
将按预期工作,无需任何其他方法定义。