2016-01-04 57 views
3

我想知道是否可以編寫一個可以在兩個數字,兩個數字列表,兩個數字矩陣等等上工作的Haskell添加運算符。也就是說,是否有可能定義一個<+>,使得所有的下列作品?:如何在Haskell中添加兩個類似matlab的列表?

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]],沿着同一行,依此類推......

但它可以使用一個運算符(因爲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]]時,當有錯誤。

+5

那麼,你可以寫一個非常類似於'Monoid'的類,它有不同的實例。 – dfeuer

+3

爲了使這個有趣,你需要提供更完整的例子。你想要什麼?[1,2] <+> [3,4]'給?那麼'[[1,2],[3,4]] <+> [[5,6],[7,8]]'?那麼'[1,2,3,4] <+> []'?有很多邊緣案例需要考慮。 –

+1

Matlab/Octave會在上一個例子中給出尺寸不匹配的錯誤,否則它是'X(i,j)+ Y(i,j)'。 –

回答

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 
    (<+>) = (+) 

優點是,一些inst王牌可能很短,例如

instance Additive Integer 
instance Additive Int 
instance Additive Double 
instance Additive Float 

將全部按預期工作,沒有任何附加的方法定義。

+0

任何優雅的方式來取代'整數'與'NUM'? –

+0

當然:'實例Num a =>添加劑a其中(<+>)=(+)' –

+0

@ReinHenrichs僅適用於'FlexibleInstances'右側的作用? –