有没有办法在Haskell中以自己的数据类型派生Num类函数?

时间:2016-01-28 09:47:24

标签: class haskell deriving

我们说我有一个类型声明:

 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
  ...

(这似乎适得其反)?

2 个答案:

答案 0 :(得分:1)

standard Haskell中没有通用的deriving:目前,deriving只能由编译器为特定的Prelude类型类定义:Read,{{1} },ShowEqOrdEnum

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
  ...