2017-02-15 16 views
6

Tôi đang cố gắng sử dụng thư viện tuyến tính của ekmett và tôi đang gặp một số sự cố với vectơ độ dài thay đổi, trong Linear.V. Làm cách nào để sử dụng hàm dim để nhận kích thước của vec-tơ? Làm cách nào để sử dụng trace trên một ma trận vuông lớn được làm bằng lồng nhau V s? Tôi gặp lỗi trong cả hai trường hợp này.Làm cách nào để sử dụng vectơ có kích thước biến trong thư viện "Tuyến tính" của Edward Kmett?

mã tối thiểu:

import qualified Data.Vector as Vector 
import Linear.V (V(V), dim) 
import Linear.Vector (outer) 
import Linear.Matrix (trace) 

v, w :: V n Double -- What do I do here? 
v = V $ Vector.fromList [1..5] 
w = V $ Vector.fromList [2, 3, 5, 7, 11] 

d = dim v 
m = outer v w 
t = trace m 

Nó cung cấp cho các lỗi mà tôi không hiểu:

• Ambiguous type variable ‘n0’ arising from a use of ‘dim’ 
    prevents the constraint ‘(Linear.V.Dim n0)’ from being solved. 
    Probable fix: use a type annotation to specify what ‘n0’ should be. 
    These potential instances exist: 
    two instances involving out-of-scope types 
    (use -fprint-potential-instances to see them all) 
• In the expression: dim v 
    In an equation for ‘d’: d = dim v 

• Ambiguous type variable ‘n1’ arising from a use of ‘trace’ 
    prevents the constraint ‘(Linear.V.Dim n1)’ from being solved. 
    Probable fix: use a type annotation to specify what ‘n1’ should be. 
    These potential instances exist: 
    two instances involving out-of-scope types 
    (use -fprint-potential-instances to see them all) 
• In the expression: trace m 
    In an equation for ‘t’: t = trace m 
+0

Bạn không nên sử dụng trực tiếp hàm tạo 'V', vì bạn có thể dễ dàng vi phạm bất biến mà chiều dài vectơ và chỉ mục mức loại cho biết độ dài không khớp. Sử dụng 'Linear.V.fromVector (fromList [1 ..5]) :: V 5 Double' - lưu ý rằng ở đây nếu bạn chỉ định độ dài sai ở mức loại thì hàm này cho bạn 'Nothing', và với kiểu này' dim' sẽ có thể thỏa mãn 'Dim n' ('Dim 5' trong trường hợp này) ràng buộc. Nếu bạn thực sự muốn loại 'tồn tại độ dài. Độ dài V X' thì loại đó chính xác là 'Vector X'. – user2407038

+1

Hmm. @ user2407038 là đúng, nhưng có một cái gì đó fishy về 'dấu vết' - vì một lý do tôi dường như không thể thuyết phục GHC rằng ràng buộc' Trace' là hài lòng ... – Alec

Trả lời

5

Bởi vì Haskell không lệ thuộc gõ, nó có thể không nâng lên mức loại chiều dài của một danh sách nó có thể chỉ nhận được khi chạy. Như đã nói, mục đích của n là bạn có thể tạo mã đa hình trên kích thước của vectơ (ví dụ: bạn có thể đảm bảo rằng bạn không lấy sản phẩm dấu chấm của vectơ có độ dài khác nhau). Nhưng bạn vẫn cần xác định rõ độ dài của vectơ thực tế của bạn tại thời gian biên dịch, nếu bạn muốn sử dụng thông tin đó.

Điều gì linearkhông cung cấp cho bạn là cho phép bạn thực hiện kiểm tra xem véc tơ bạn đã khớp với loại bạn đã chỉ định hay chưa. Ví dụ,

ghci> :set +t -XDataKinds -XOverloadedLists 
ghci> import Linear 
ghci> import Linear.V 
ghci> fromVector [1,2,3] :: Maybe (V 3 Int) 
Just (V {toVector = [1,2,3]}) 
it :: Maybe (V 3 Int) 
ghci> fromVector [1,2,3] :: Maybe (V 2 Int) 
Nothing 
it :: Maybe (V 3 Int) 

Vì vậy, trong trường hợp của bạn, bạn có lẽ nên được làm một cái gì đó như sau:

ghci> Just v = fromVector [1..5]   :: Maybe (V 5 Double) 
v :: V 5 Double 
ghci> Just w = fromVector [2, 3, 5, 7, 11] :: Maybe (V 5 Double) 
w :: V 5 Double 
ghci> dim v 
5 
it :: Int 
ghci> m = outer v w 
m :: V 5 (V 5 Double) 
ghci> trace m 
<interactive>:44:1: error: 
    • No instance for (Trace (V 5)) arising from a use of ‘trace’ 
    • In the expression: trace m 
    In an equation for ‘it’: it = trace m 

... annnnd yeah - Tôi nghĩ rằng tương tác cuối cùng là một lỗi (trừ khi ai đó có thể thấy một cái gì đó tôi đang thiếu). Biến thể Trace (V 5) phải thỏa mãn mặc dù phiên bản Dim n => Trace (V n) nhưng vì một lý do nào đó thì không.

EDIT

Như @ user2407038 đã chỉ ra, vấn đề là các Dim n => Trace (V n) tôi đã đề cập ở trên được không polykinded - nó chỉ hoạt động cho n :: * trong khi chúng tôi muốn nó làm việc cho bất kỳ loại (đặc biệt n :: Nat trong trường hợp này). Không có bất kỳ lý do thực sự cho hạn chế này, vì vậy chúng tôi có thể đi trước và xác định phiên bản riêng của chúng ta về dụ

ghci> :set -XPolyKinds 
ghci> instance Dim n => Trace (V n) 
ghci> trace m 
106.0 

tôi đã mở một issue.

CHỈNH SỬA 2

Sự cố đã được khắc phục. Tôi nghĩ rằng nó có lẽ nên làm cho nó vào phiên bản tiếp theo của linear.


Như một mặt lưu ý, tôi sử dụng -XDataKinds để tôi được phép viết chữ kiểu cấp (trong đó có loại GHC.TypeLits.Nat - họ là đặc biệt và Hardwired vào GHC) và -XOverloadedLists vì vậy tôi có thể viết [1..5] :: Vector Int.

+2

'Dấu vết (V 5)' không hài lòng vì các loại là sai, ví dụ thực sự là 'Dim * n => Dấu vết (V * n)' nhưng bạn sẽ cần 'Dim Nat n => Dấu vết (V Nat n)' hoặc thông thường hơn 'Dim kn => Dấu vết (V kn) '. Có lẽ đây chỉ là một lỗi, nhưng bạn vẫn có thể tự khai báo cá thể thích hợp như một sửa chữa nhanh. – user2407038

+1

@ user2407038 Ah yes. Đẹp bắt - Tôi nghi ngờ một cái gì đó của loại nhưng đã không khá nhận được ở đó. Tôi sẽ chỉnh sửa câu trả lời và cũng có thể mở một lỗi. – Alec

+1

Lỗi [mở] (https://github.com/ekmett/linear/issues/121). – Alec

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