1

假设我有一个类型声明:

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

(这似乎适得其反)?

4

2 回答 2

2

标准 Haskell中没有deriving可用的泛型:目前,仅在编译器为特定 Prelude 类型类定义时可用:、、、、和。derivingReadShowEqOrdEnumBounded

Glasgow Haskell Compiler (GHC) 显然具有支持 generic的扩展deriving。但是,我不知道它是否真的会为您节省任何尝试使用它们的工作:您需要从多少个类型类派生一个Num实例?而且,您确定您可以定义一个自动派生方案,该方案Num将始终如您所愿吗?

如评论中所述,您需要描述您的Num实例在任何情况下都会做什么。描述和调试一个通用的方案肯定比描述一个特定的方案需要更多的工作。

于 2016-01-28T17:52:40.217 回答
1

不,您不能自动执行此操作,但我认为 leftaroundabout 可能得到的是您可以使用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
  ...
于 2016-01-28T19:25:40.633 回答