提升自动haskell派生声明

时间:2016-03-21 09:42:01

标签: haskell typeclass deriving

有没有办法让编译器派生我手动编写的功能:

instance Class c => Class (Trans c) where
    foo1 = lift foo1
    foo2 = lift foo2
    ...
    foo999 = lift foo999
    bar1 = \a b c -> lift $ bar1 a b c
    ...
    baz1 = lift . baz1
    ...

即。当Class中包含类Trans时,是否可以自动为Class获取Trans的免费实例,而无需进行繁重的工作:) ?

1 个答案:

答案 0 :(得分:1)

如果lift本身是一个类型类函数,则可以为类型类的所有实例编写一般定义。类似的东西:

instance (Class c, Trans t) => Class (t c)

请注意,这不会与任何其他实例重叠,并且是您想要的所有这些类型。

作为一个更完整的例子,这段代码可行,即使它的结果有时令人惊讶。

{-# LANGUAGE FlexibleInstances #-}

module Inst where

import Control.Applicative (liftA2)

instance (Applicative f, Num n) => Num (f n) where
  (+) = liftA2 (+)
  (*) = liftA2 (*)
  abs = fmap abs
  signum = fmap signum
  fromInteger = pure . fromInteger
  negate = fmap negate