Hạn chế giá trị được tham chiếu trong cảnh báo là một trong những điều khó hiểu hơn trong SML, tuy nhiên tôi sẽ cố hết sức để giải thích lý do xảy ra trong trường hợp này và cố gắng hướng bạn đến một số tài nguyên để tìm hiểu hơn.
Như bạn đã biết, SML sẽ sử dụng suy luận kiểu để suy ra hầu hết các loại trong chương trình của bạn. Trong chương trình này, loại my_func
sẽ được suy ra là ('a -> 'b option) -> 'a list -> 'b
. Như bạn đã lưu ý, đó là một loại đa hình. Khi bạn gọi my_func
như thế này
myfunc f [NONE, SOME 1, NONE];
... các biến kiểu 'a
và 'b
được khởi tạo để int option
và int
.
Tuy nhiên khi bạn gọi nó mà không có một giá trị như SOME 1
trên
myfunc f [NONE, NONE];
Bạn nghĩ gì các biến loại nên được instantiated để? Các loại phải có dạng đa hình - chẳng hạn như 't option
và 't
cho tất cả các loại 't
. Tuy nhiên, có một giới hạn ngăn chặn các giá trị như thế này để đưa vào các loại đa hình.
SML định nghĩa một số biểu thức dưới dạng giá trị không mở rộng và chỉ những giá trị này có thể có trên các loại đa hình.Đó là:
- literals (hằng số)
- biến
- chức năng biểu thức
- nhà xây dựng (trừ
ref
) áp dụng cho các giá trị phi mở rộng
- một giá trị không phải là mở rộng với một loại chú thích
- bộ dữ liệu trong đó mỗi trường là giá trị không mở rộng
- ghi lại nơi mỗi trường là giá trị không mở rộng
- danh sách đó mỗi lĩnh vực là một giá trị không phải là mở rộng
Tất cả những biểu hiện khác, đáng chú ý chức năng gọi (đó là những gì các cuộc gọi đến my_func
là) không thể đa hình. Không thể tham khảo. Bạn có thể tò mò muốn thấy những điều sau đây không làm tăng một cảnh báo:
fn() => my_func f [NONE, NONE];
Thay vào đó, các loại suy ra là unit -> 'a
. Tuy nhiên, nếu bạn gọi hàm này, bạn sẽ nhận được cảnh báo lần nữa.
Sự hiểu biết của tôi về lý do hạn chế này hơi yếu, nhưng tôi tin rằng vấn đề gốc cơ bản là các tham chiếu có thể thay đổi. Dưới đây là ví dụ tôi đã thực hiện từ trang web MLton được liên kết bên dưới:
val r: 'a option ref = ref NONE
val r1: string option ref = r
val r2: int option ref = r
val() = r1 := SOME "foo"
val v: int = valOf (!r2)
Chương trình này không đánh máy theo SML do hạn chế về giá trị. Không phải vì hạn chế giá trị, chương trình này sẽ có lỗi kiểu khi chạy.
Như tôi đã nói, sự hiểu biết của tôi là run rẩy. Tuy nhiên tôi hy vọng tôi đã làm sáng tỏ một chút về vấn đề bạn đã gặp phải, mặc dù tôi tin rằng trong trường hợp của bạn, bạn có thể bỏ qua cảnh báo một cách an toàn. Dưới đây là một số tài liệu tham khảo, bạn nên quyết định bạn muốn đào sâu hơn:
http://users.cis.fiu.edu/~smithg/cop4555/valrestr.html
http://mlton.org/ValueRestriction
(BTW trang MLton là vàng rắn Có rất nhiều ẩn đi ở đây, vì vậy nếu bạn. đang cố hiểu điều gì đó kỳ lạ về SML, tôi khuyên bạn nên tìm kiếm ở đây vì bạn có thể sẽ tăng lên nhiều hơn mức bạn muốn ban đầu)
Vì có vẻ như bạn đang sử dụng SML/NJ, đây là hướng dẫn khá tiện dụng cho er thông điệp ROR và cảnh báo rằng nó sẽ cung cấp cho bạn tại thời gian biên dịch:
http://flint.cs.yale.edu/cs421/smlnj/doc/errors.html
Cảm ơn bạn rất nhiều vì trả lời thông tin của bạn! Tôi sẽ xem xét các tài nguyên được đề xuất của bạn để nghiên cứu thêm và sẽ báo cáo lại nếu tôi tìm cách giải quyết thông báo cảnh báo này. Như bạn đã nói, có thể không có khả năng cho những trường hợp thử nghiệm nào đó trống hoặc chỉ chứa NONE, do tính chất đa hình của chúng. Cảm ơn một lần nữa vì sự giúp đỡ của bạn. – mbear
Không sao, tôi rất vui được giúp đỡ.Một vài điều bạn có thể làm để loại bỏ cảnh báo là (1) chú thích với bất kỳ kiểu nào, làm cho giá trị không còn đa hình tất nhiên: '(my_func f [NONE, NONE]): int' hoặc (2) chỉ nhận cảnh báo này xảy ra khi nhập một giá trị như thế này trong REPL, và có lẽ sẽ không được nâng lên trong một chương trình lớn hơn gọi 'my_func' với các dữ liệu khác. – spacemanaki
Haskell có phiên bản lạ lùng này hay thiếu tài liệu tham khảo có thể thay đổi được không? –