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がラップされている場合、手間のかかる作業を行わなくても、 forTransの無料インスタンスClassTrans自動的に取得することは可能ですか :)?

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 に答える