5

adパッケージに含まれる型の基本的な配管に頭を悩ませることにほとんど成功していません。たとえば、次のコードは完全に機能します。

import Numeric.AD

ex :: Num a => [a] -> a
ex [x, y] = x + 2*y

> grad ex [1.0, 1.0]
[1.0, 2.0]

gradタイプは次のとおりです。

grad
  :: (Num a, Traversable f) =>
     (forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
     -> f a -> f a

extoの型シグネチャを変更し[Double] -> Doubleて同じことを試すと、

Couldn't match expected type `AD s a0' with actual type `Double'
Expected type: f0 (AD s a0) -> AD s a0
  Actual type: [Double] -> Double

をインスタンス化Doubleする種類の一見任意の型コンストラクターに置き換えると、同じ動作が発生します。 *Num

がリストの場合Traversable f、 の最初の引数は、許容されるgrad型(たとえば. しかし明らかに、 のユーザーは、コンストラクターや を直接処理する必要はありません。これらの内部を覗いてみると、私は少し混乱しました。具体的には、との使用の違いについて、種類/型の軌跡をたどることができません。 [AD s a] -> AD s aModeReversegradADModeNum a => [a] -> a[Double] -> Double

[Double] -> Double型シグネチャが で問題を引き起こすのはなぜgradですか? そして、単純な古いライブラリの使用に関して: の[Double] -> Doubleバージョンを使用する方法はありますかex、それともポリモーフィック バージョンが必要ですか?

(この同様の質問に触発されたタイトル)

4

1 に答える 1

6

adライブラリはわかりませんが、は最初のパラメータとしてgradtype の関数を[AD s a] -> AD s a期待しているため、 type の関数を渡すことができるとは期待できません。とは完全に異なる型[Double] -> Doubleだからです。DoubleAD

それ自体が のインスタンスでもあるNumため、制約付きのジェネリック関数は機能します。したがって、実際の例では、次のようなものに特化されますADNumex

ex :: (Mode s, Fractional a) => [AD s a] -> AD s a

Doubles を使用した計算に特化したい場合はex、次のような署名を付ける必要があります。

ex :: Mode s => [AD s Double] -> AD s Double
于 2012-07-25T18:32:01.790 に答える