1

型宣言があるとしましょう:

 data MyType = N Double | C Char | Placeholder

Num、Real、Fractional のすべての関数が、N コンストラクターでラップされた引数の N (通常の結果) になり、他の引数の Placeholder が得られるように、可能な限り MyType を Double として処理できるようにしたいと考えています。

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

標準の Haskellderivingで使用できるジェネリックはありません。現在、特定の Prelude 型クラス ( 、 、 、 、および ) に対してコンパイラによって定義されている場合にのみ使用できます。derivingReadShowEqOrdEnumBounded

Glasgow Haskell Compiler (GHC) には明らかにgeneric をサポートする拡張機能derivingがあります。ただし、実際にそれらを試して使用する手間が省けるかどうかはわかりませんNum。インスタンスを派生させるには、いくつの型クラスが必要ですか? そして、あなたが望むことを常に行う導出のための自動スキームを定義できると確信していNumますか?

コメントに記載されているように、Numインスタンスがどのような場合に何を行うかを説明する必要があります。また、一般的なスキームを記述してデバッグすることは、特定のスキームを記述するよりも確実に手間がかかります。

于 2016-01-28T17:52:40.217 に答える
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
  ...
于 2016-01-28T19:25:40.633 に答える