如何在Haskell中添加两个像matlab这样的列表?

时间:2016-01-04 05:42:16

标签: matlab haskell

我想知道是否可以编写一个Haskell add运算符,它可以处理两个数字,两个数字列表,两个数字矩阵,......等等。也就是说,是否可以定义<+>以使以下所有方法都有效?:

1 <+> 2 = 3
[1] <+> [2] = [3]
[[1]] <+> [[2]] = [[3]]
...

我知道,就像在What is an idiomatic way to add lists in Haskell?中一样,+ azipWith (+) [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(); } } } } 时都会出错。

1 个答案:

答案 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

将按预期工作,无需任何其他方法定义。