2010-06-05 25 views
11

Tôi muốn các toán tử tốt cho số học phức tạp để làm cho mã của tôi dễ đọc hơn. Ocaml có một mô-đun phức tạp, vì vậy tôi chỉ muốn thêm các toán tử gọi các hàm đó.Ocaml quyết định ưu tiên cho các toán tử do người dùng xác định như thế nào?

Cách trực quan nhất đối với tôi là tạo một toán tử phức tạp mới từ tất cả các toán tử thông thường bằng cách gắn thêm '&' vào ký hiệu toán tử. Do đó, + & và * & sẽ là phép cộng và nhân phức tạp. Tôi cũng muốn ~ & là cách chia phức tạp.

Nếu tôi định sử dụng các toán tử này, tôi muốn chúng liên kết giống như cách mà số học bình thường liên kết. Dựa trên các phiên tiếp theo, chúng sẽ tự động hoạt động theo cách tôi muốn, nhưng tôi muốn hiểu tại sao, để tôi không gặp phải những lỗi khủng khiếp khi tôi giới thiệu nhiều nhà khai thác hơn.

Dự đoán hiện tại của tôi là ưu tiên của chúng được thực hiện bằng cách sắp xếp ký hiệu toán tử theo thứ tự phù hợp với mức ưu tiên số học bình thường. Nhưng tôi không thể xác nhận điều này.

phiên một:

# open Complex;; 
# let (+&) a b = add a b;; 
val (+&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# let (*&) a b = mul a b;; 
val (*&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# one +& zero *& one +& zero *& one;; 
- : Complex.t = {re = 1.; im = 0.} 
# zero +& one *& zero +& one *& zero;; 
- : Complex.t = {re = 0.; im = 0.} 
# i +& i *& i +& i *& i *& i;; 
- : Complex.t = {re = -1.; im = 0.} 

phiên hai:

# open Complex;; 
# let (*&) a b = mul a b;; 
val (*&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# let (+&) a b = add a b;; 
val (+&) : Complex.t -> Complex.t -> Complex.t = <fun> 
# one +& zero *& one +& zero *& one;; 
- : Complex.t = {re = 1.; im = 0.} 
# zero +& one *& zero +& one *& zero;; 
- : Complex.t = {re = 0.; im = 0.} 
# i +& i *& i +& i *& i *& i;; 
- : Complex.t = {re = -1.; im = 0.} 
# let (~&) a = conj a;; 
val (~&) : Complex.t -> Complex.t = <fun> 
# (one +& i) *& ~& (one +& i);; 
- : Complex.t = {re = 2.; im = 0.} 

Trả lời

13

Nhìn chung, associativity và ưu tiên của một nhà điều hành (trừ khi bạn đi ra ngoài để camlp4 hoặc một cái gì đó) được dựa trên ký tự đầu tiên của toán tử.

source (tìm kiếm "Ưu tiên tương đối cho người dùng do người dùng xác định").

Không có cách nào để xác định nó một cách rõ ràng trong OCaml (xem this và cũng "khai thác ghi vào người dùng định nghĩa" trên Comparing Objective Caml and Standard ML)

Bạn có thể sử dụng camlp4 hoặc camlp5 để xác định một cách rõ ràng theo thứ tự của chức năng ghi vào. Có vẻ như pa_do cũng có thể là một tùy chọn.

Tôi đã cố gắng viết một ví dụ nhưng tôi không quen với các camlp4 và không dễ học trong vài phút nữa.

+0

Cảm ơn! Tôi thấy khó chịu vì câu trả lời đúng không hữu ích và/hoặc tuyệt vời hơn. Tôi cũng không đủ quen thuộc với p4/p5 để sử dụng nó. – forefinger

+2

Liên kết tuyệt vời. Tôi sẽ đề cập đến camlp {4,5}, nhưng việc sửa lỗi ưu tiên của các toán tử chỉ là ý nghĩa trong câu hỏi ban đầu. Sự kết thúc là làm cho mã tương lai.Tôi nghi ngờ bất kỳ giải pháp nào liên quan đến camlp {4,5} là một giải pháp tốt đối với mục tiêu này; nó chắc chắn là một phụ thuộc tôi cố gắng tránh, mặc dù nó thường hấp dẫn. –

14

Ngay trong hướng dẫn OCaml, section 6.7, cuộn xuống, ngay trước phần 6.7.1. Bảng ưu tiên có một số thứ như +..., bao gồm bất kỳ người dùng nào được xác định bắt đầu bằng +. Không đúng là nó luôn phụ thuộc vào ký tự đầu tiên, vì **... có độ ưu tiên cao hơn *....

3

Phần mở rộng cú pháp pa-làm cho OCaml địa chỉ chính xác vấn đề này:

http://pa-do.forge.ocamlcore.org/

Bạn có thể sử dụng nó để thay đổi hành ưu tiên, hay, hữu ích hơn trong trường hợp này, sử dụng bối cảnh rõ ràng để thay đổi ý nghĩa của các nhà khai thác.

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