我想知道是否有可能编写一个Haskell添加运算符,它可以处理两个数字,两个数字列表,两个数字矩阵,......等等.也就是说,是否可以定义<+>以下所有内容?:
1 <+> 2 = 3
[1] <+> [2] = [3]
[[1]] <+> [[2]] = [[3]]
...
Run Code Online (Sandbox Code Playgroud)
我知道,在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 (<+>)
Run Code Online (Sandbox Code Playgroud)
要么
{-# LANGUAGE DefaultSignatures #-}
class Additive a where
(<+>) :: a -> a -> a
default (<+>) :: Num a => a -> a -> a
(<+>) = (+)
Run Code Online (Sandbox Code Playgroud)
在任何一种情况下,加载.hs文件或评估时都会出错[[1,2]] <+> [[3,4]].
是的,这是可能的:
class Additive a where (<+>) :: a -> a -> a
instance Additive Integer where (<+>) = (+)
instance Additive a => Additive [a] where (<+>) = zipWith (<+>)
Run Code Online (Sandbox Code Playgroud)
您在ghci中的三个测试用例:
*Main> 1 <+> 2
3
*Main> [1] <+> [2]
[3]
*Main> [[1]] <+> [[2]]
[[3]]
Run Code Online (Sandbox Code Playgroud)
如果您需要大量实例(<+>) = (+),可以将其作为默认实现DefaultSignatures:
{-# LANGUAGE DefaultSignatures #-}
class Additive a where
(<+>) :: a -> a -> a
default (<+>) :: Num a => a -> a -> a
(<+>) = (+)
Run Code Online (Sandbox Code Playgroud)
优点是某些情况可能非常短,例如
instance Additive Integer
instance Additive Int
instance Additive Double
instance Additive Float
Run Code Online (Sandbox Code Playgroud)
将全部按预期工作,无需任何其他方法定义.
| 归档时间: |
|
| 查看次数: |
148 次 |
| 最近记录: |