Numeric.AD 関数で受け入れられる型
-
11-12-2019 - |
質問
私は、この問題に関係する種類の基本的な配管を理解するのにほとんど成功していません。 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