2017-06-09 14 views
5

tôi stumbled khi được thông báo biên soạn sau đây trong OCaml:Khi nào áp lực kép là hữu ích?

This simple coercion was not fully general. Consider using a double coercion. 

Nó đã xảy ra trong một mã nguồn khá phức tạp, nhưng đây là một MNWE:

open Eliom_content.Html.D 

let f_link s = 
    let arg : Html_types.phrasing_without_interactive elt list = [pcdata "test"] in 
    [ Raw.a ~a:[a_href (uri_of_string (fun() -> "test.com"))] arg ] 

type tfull = (string -> Html_types.flow5 elt list) 
type tphrasing = (string -> Html_types.phrasing elt list) 

let a : tfull = ((f_link :> tphrasing) :> tfull) 

let b : tfull = (f_link :> tfull) 

Bạn có thể biên dịch ví dụ này với ocamlfind ocamlc -c -package eliom.server -thread test.ml, với Đã cài đặt Eliom 6.

Lỗi xảy ra trên dòng cuối cùng, nơi trình biên dịch OCaml phàn nàn rằng f_link không thể chuyển đổi thành loại tfull.

Ai đó có thể giải thích cho tôi tại sao nó không thể ép buộc f_link-tfull trực tiếp, nhưng nó thể ép buộc nó để tfull gián tiếp sử dụng tphrasing như một bước trung?

Bất kỳ con trỏ nào đến lý thuyết loại đằng sau nó cũng sẽ được chào đón.

Trả lời

7

Nhà điều hành ép buộc nói chung, còn được gọi là một coersion đôi, có một hình thức

(<exp> : <subtype> :> <type>) 

Loại <subtype> có thể được đôi khi bỏ qua, trong trường hợp đó nó được gọi là một sự ép buộc duy nhất. Vì vậy, trong trường hợp của bạn, việc cưỡng chế đúng sẽ trông như thế này:

let a : tfull = (f_link : f_link_type :> tfull) 

nơi f_link_type là một loại của f_link chức năng.

Lý do tại sao nó có thể thất bại được mô tả trong the manual:

Nhà điều hành cũ đôi khi sẽ thất bại trong việc ép buộc một biểu thức expr từ một loại typ1 đến một loại typ2 ngay cả khi loại typ1 là một subtype loại typ2: trong triển khai hiện tại, nó chỉ mở rộng hai cấp kiểu chữ viết tắt chứa các đối tượng và/hoặc biến thể đa hình, giữ chỉ đệ quy khi nó rõ ràng trong loại lớp (đối tượng). Là ngoại lệ cho thuật toán trên, nếu cả loại được suy ra là expr và nhập là mặt đất (nghĩa là không chứa biến kiểu), toán tử trước đây hoạt động như toán tử thứ hai, lấy loại được suy ra là expr làm typ1. Trong trường hợp thất bại với nhà điều hành cũ, sau nên được sử dụng.

Hãy để tôi cố gắng đưa nó vào các thuật ngữ đơn giản hơn. Việc ép buộc chỉ có thể xảy ra nếu cả tên miền và tên miền được biết. Tuy nhiên, trong nhiều trường hợp, bạn có thể áp dụng một heuristic sẽ suy ra tên miền từ tên miền và loại biểu thức hiện tại. Điều này làm việc heuristic nếu loại biểu hiện là mặt đất, không có cuộc tiếp tục, và một số hạn chế khác. Về cơ bản, nếu kiểu miền không có kiểu chung chung nhất, chúng ta cần liệt kê tất cả các khái quát có thể và kiểm tra mọi kết hợp có thể có.

+1

RTFM đẹp nhất mà tôi từng thấy :-) Thật vậy '(f_link: tphrasing:> tfull)' hoạt động như mong đợi, tôi không biết về thuật toán liên quan như vậy để tìm kiếm các loại tương thích. Cám ơn bạn rất nhiều về thông tin đó! –

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