我们说我有一个类型声明:
data MyType = N Double | C Char | Placeholder
我希望能够在任何可能的情况下将MyType视为Double,所有Num,Real,Fractional函数都会为N构造函数中包含的参数生成N(正常结果),并为其他函数生成占位符参数
> (N 5.0) + (N 6.0)
N 11.0
> (N 5.0) + (C 'a')
Placeholder
有没有办法做到这一点,而不是简单地将这个类定义为这些类的实例,方式类似于:
instance Num MyType where
(+) (N d1) (N d2) = N (d1+d2)
(+) _ _ = Placeholder
...
(这似乎适得其反)?
答案 0 :(得分:1)
standard Haskell中没有通用的deriving
:目前,deriving
只能由编译器为特定的Prelude类型类定义:Read
,{{1} },Show
,Eq
,Ord
和Enum
。
Glasgow Haskell编译器(GHC)显然有extensions支持通用Bounded
。但是,我不知道它是否真的会省去你尝试使用它们的任何工作:你需要从多少类型类派生一个deriving
实例?并且,您确定可以定义一个自动方案来导出Num
,它总能做到您想要的吗?
如评论中所述,您需要描述Num
实例在任何情况下的操作。描述和调试一般方案肯定比描述特定方案更有用。
答案 1 :(得分:1)
不,你不能自动执行此操作,但我认为左下角可能会有的是你可以使用Applicative
操作来帮助你。
data MyType n = N n | C Char | Placeholder deriving (Show, Eq, Functor)
instance Applicative MyType where
pure = N
(<*>) = ap
instance Monad MyType where
N n >>= f = f n
C c >>= _ = C c
Placeholder >>= _ = Placeholder
现在你可以写
了instance Num n => Num (MyType n) where
x + y = (+) <$> x <*> y
abs = fmap abs
...