5

Tôi đang có ít thành công trong đầu quanh ống dẫn cơ bản của các loại có liên quan trong gói ad. Ví dụ, sau đây hoạt động hoàn hảo:Các loại có thể chấp nhận trong các hàm Numeric.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] 

nơi grad có các loại:

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

Nếu tôi thay đổi kiểu chữ ký của ex-[Double] -> Double và cố gắng điều tương tự, tôi nhận được

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 

Hành vi tương tự xảy ra khi thay thế Double với bất kỳ kiểu hàm tạo nào bằng loại * mà instantiates Num.

Khi Traversable f là một danh sách, đối số đầu tiên của grad phải có loại [AD s a] -> AD s a đối với một số chấp nhận được Mode - ví dụ, Reverse. Nhưng rõ ràng người dùng của grad không phải xử lý trực tiếp với hàm tạo AD hoặc trực tiếp Mode. Nhìn trộm vào những cái bên trong này khiến tôi hơi bối rối; cụ thể, tôi không thể theo dõi đường mòn loại/loại đến sự khác biệt giữa việc sử dụng Num a => [a] -> a[Double] -> Double.

Tại sao loại chữ ký [Double] -> Double gây ra sự cố với grad? Và về mặt sử dụng thư viện cũ: có cách nào để sử dụng phiên bản [Double] -> Double của ex hoặc phiên bản đa hình cần thiết không?

(tiêu đề lấy cảm hứng từ this similar question)

Trả lời

6

Tôi không biết thư viện ad, nhưng kể từ khi grad hy vọng một chức năng của loại [AD s a] -> AD s a như tham số đầu tiên của nó, bạn không thể mong đợi để có thể vượt qua nó một chức năng của loại [Double] -> Double, kể từ DoubleAD là các loại hoàn toàn khác nhau.

Chức năng chung với Num hạn chế hoạt động, vì AD bản thân cũng là một thể hiện của Num, do đó trong ví dụ làm việc của bạn, ex bị chuyên dùng để cái gì đó như

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

Nếu bạn muốn chuyên ex cho các tính toán sử dụng Tăng gấp đôi, bạn cần cung cấp cho nó một chữ ký như

ex :: Mode s => [AD s Double] -> AD s Double 
+0

Ahhhh ok, do đó, 'AD' là một thể hiện của' Num'. Tôi không nhận thấy rằng trong danh sách các trường hợp, nhưng tôi thấy nó ngay bây giờ. – jtobin

+2

Ngoài ra, nếu bạn có một số hằng số nằm xung quanh là Tăng gấp đôi, giả sử, trong các cấu trúc dữ liệu khác, bạn có thể cần sử dụng Numeric.AD.Types.lift hoặc các bộ kết hợp khác trong Chế độ để chúng tương tác với các đối số Đôi và kết quả của AD . –

Các vấn đề liên quan