Sau khi viết đoạn mã nàyOCaml phương sai (+ 'một, -'a) và bất biến
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {info : 'a list}
end
tôi nhận ra tôi cần info
là có thể thay đổi.
tôi đã viết, sau đó:
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {mutable info : 'a list}
end
Nhưng, bất ngờ,
Type declarations do not match:
type 'a t = { mutable info : 'a list; }
is not included in
type +'a t
Their variances do not agree.
Ồ, tôi nhớ đã nghe về sai. Đó là một cái gì đó về hiệp phương sai và contravariance. Tôi là một người dũng cảm, tôi sẽ tìm hiểu về vấn đề của tôi một mình!
Tôi đã tìm thấy hai bài viết thú vị này (here và here) và tôi đã hiểu!
tôi có thể viết
module type TS = sig
type (-'a, +'b) t
end
module T : TS = struct
type ('a, 'b) t = 'a -> 'b
end
Nhưng sau đó tôi tự hỏi. Các kiểu dữ liệu có thể thay đổi là bất biến và không chỉ là biến thể?
Ý tôi là, tôi hiểu rằng 'A list
có thể được coi là loại phụ của ('A | 'B) list
vì danh sách của tôi không thể thay đổi. Cùng một chức năng, nếu tôi có chức năng kiểu 'A | 'B -> 'C
, nó có thể được coi là một kiểu con của hàm 'A -> 'C | 'D
vì nếu hàm của tôi có thể xử lý 'A
và 'B
thì nó chỉ có thể xử lý 'A
và nếu tôi chỉ trả về 'C
's tôi có thể chắc chắn mong đợi 'C
hoặc 'D
' s (nhưng tôi sẽ chỉ nhận được 'C
's).
Nhưng đối với một mảng? Nếu tôi có một 'A array
Tôi không thể xem xét nó như là một ('A | 'B) array
bởi vì nếu tôi sửa đổi một phần tử trong mảng đặt một 'B
thì loại mảng của tôi là sai bởi vì nó thực sự là một ('A | 'B) array
và không phải là 'A array
nữa. Nhưng còn một số ('A | 'B) array
là 'A array
. Có, nó sẽ là lạ vì mảng của tôi có thể chứa 'B
nhưng kỳ lạ tôi nghĩ nó giống như một hàm. Có lẽ, cuối cùng, tôi không hiểu hết mọi thứ nhưng tôi muốn suy nghĩ về nó ở đây bởi vì tôi mất nhiều thời gian để hiểu nó.
TL; DR:
dai dẳng:
+'a
chức năng:
-'a
có thể thay đổi: bất biến (
'a
)? Tại sao tôi không thể ép buộc nó là-'a
?
Chính xác loại câu trả lời tôi mong đợi để bài đăng này có thể giúp các nhà phát triển OCaml trong tương lai hiểu dễ dàng và nhanh chóng vấn đề về phương sai này. – Lhooq
Tôi nghĩ rằng bạn có nghĩa là "và * setter * là loại ..." - gửi một chỉnh sửa, hy vọng tôi đã không nhận được sửa chữa sai! Thực sự vấp phải điều đó trong vài phút. – ELLIOTTCABLE
vâng, chắc chắn :) Cảm ơn! – ivg