2017-04-13 13 views
7

Trong F # 's printf có định dạng thông số %A cho phép truyền vào bất kỳ loại F # nào, và nó sẽ được đánh giá và in.Tại sao% A specifier trong printf của F # không tồn tại trong printf của OCaml?

Như một ví dụ:

type Result<'a> = 
    | Failure 
    | Success of 'a  

printf "%A" (Success "hello") // prints out 'Success "hello"' 

đâu, rõ ràng, Result<'a> không phải là một built-in loại.

Tôi có thể khai báo kiểu tương tự trong OCaml, nhưng không có thông số tương đương cho Printf.printf - thay vào đó, tôi sẽ phải triển khai hàm string_of_result của riêng mình và sử dụng số %s trong chuỗi định dạng. Hơn nữa, vì đây là một loại đa hình, tôi sẽ phải tạo ra một hàm không đơn giản có thể xử lý bất kỳ thể hiện kiểu nào của 'a.

Câu hỏi của tôi là - tại sao OCaml thiếu thông số tiện dụng này? Có phải vì không có động lực để thực hiện nó? Có phải bởi vì có một số thiếu mojo dưới mui xe, mà chỉ có trong F #?

Trả lời

7

Tôi muốn nói "thiếu mojo dưới mui xe" có lẽ là lý do.

Trong F #, %A trình xác định ngăn chặn in tới máy in dựa trên phản chiếu - nó sử dụng thông tin loại thời gian chạy để duyệt và in giá trị. API phản chiếu được sử dụng trong quá trình đó là một điều cụ thể về .NET. Ngoài ra, trong khi tiện dụng, nó cũng là một cơ chế tương đối đắt tiền - nó không nên được sử dụng như một bộ thông số chăn nếu bạn có thể sử dụng một cái cụ thể hơn.

Từ những gì tôi biết, OCaml không có khả năng phản chiếu tương ứng có thể được sử dụng tại đây. Có lẽ có một cơ chế khác sẽ cho phép bạn thực hiện một bản in chung - nhưng tôi không đủ quen thuộc với nội bộ OCaml để kể.

6

Cách thông thường để thực hiện việc này trong OCaml là sử dụng thông số %a và viết (hoặc lấy được) máy in cho result để chuyển cho nó.

Đó có thể trông như thế này:

type 'a result = 
    | Success of 'a 
    | Failure 
[@@deriving show] 

Format.printf "%a" (pp_result Format.pp_print_string) (Success "hello") 

nơi pp_result đã được tạo ra bởi các khoản deriving. Lưu ý rằng pp_result có chức năng định dạng làm đối số mà nó sử dụng để in bất kỳ 'a s nào.

OCaml xóa các loại (gần như) hoàn toàn trong quá trình biên dịch, vì vậy không thể sử dụng phản chiếu để thực hiện chức năng in tự động như trong F #. Tuy nhiên, rõ ràng là sự phản chiếu sẽ hoạt động tốt trong một ngôn ngữ với các kiểu trừu tượng.

+0

Giống như bổ sung: giải pháp này cần xử lý bằng ppx - khi tôi chỉ sao chép và dán mã vào REPL, '' 'pp_result''' vẫn chưa được xác định. –

+0

@ lambda.xy.x - Tôi cũng nhận thấy nó. Đối với một số lý do tôi đã có 'ppx_deriving' được cài đặt thông qua' opam', nhưng bây giờ một lỗi được ném: 'Không thể xác định vị trí deriver show'. – asafc

+1

Vâng, tôi không muốn làm phức tạp câu trả lời thực sự là về các đặc tả 'printf' với các chi tiết về việc xây dựng/cấu hình' ppx_deriving'. (Để tham khảo: trong phần toplevel, '#use 'topfind" 'và sau đó' #require "ppx_deriving.show" '. Nhưng xem tài liệu' ppx_deriving' để biết chi tiết.) – gsg

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