質問

私は、この問題に関係する種類の基本的な配管を理解するのにほとんど成功していません。 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

の型シグネチャを変更すると、 ex[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 kind を持つ一見任意の型コンストラクターを使用 * インスタンス化するもの Num.

とき Traversable f はリストであり、の最初の引数は grad 型が必要です [AD s a] -> AD s a ある程度は許容できる Mode - 例: Reverse. 。しかし、明らかにユーザーは、 grad に対処する必要はありません AD コンストラクターまたは Mode 直接。これらの内部を覗いてみると、私は少し混乱してしまいました。具体的には、種類とタイプの違いを追跡することができません。 Num a => [a] -> a そして [Double] -> Double.

なぜ型署名は [Double] -> Double ~との問題を引き起こす grad?そして、昔ながらのライブラリの使用に関しては、次のようになります。を使う方法はありますか? [Double] -> Double のバージョン ex, 、それともポリモーフィックバージョンが必要ですか?

(タイトルは以下からインスピレーションを受けました) この同様の質問)

役に立ちましたか?

解決

わかりません ad 図書館ですが、それ以来 grad 次の型の関数を期待します [AD s a] -> AD s a 最初のパラメータとして次の型の関数を渡すことは期待できません。 [Double] -> Double, 、 以来 Double そして AD 全く異なるタイプです。

汎用関数 Num 制約が機能するため、 AD それ自体もまた、 Num, したがって、実際の例では、 ex 次のようなものに特化します

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

特化したいなら ex Double を使用した計算の場合は、次のような署名を与える必要があります。

ex :: Mode s => [AD s Double] -> AD s Double
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top