1

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

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,是否可以自动获得Classfor的免费实例Trans而无需进行繁重的工作:)?

4

1 回答 1

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
于 2016-03-22T17:18:02.850 回答