2013-06-18 58 views
6

Tôi hiện đang cố gắng thực hiện một số chế biến tay mahjong trong OCaml và ngay từ đầu tôi đang phải đối mặt với một cái gì đó gây lỗi cho tôi.Các loại biến thể và kiểu phụ được đặt hàng trong OCaml

Tôi sẽ cung cấp cho bạn các ví dụ dựa trên thẻ vì tôi không muốn gây nhầm lẫn cho bất kỳ ai có thuật ngữ mạt chược.

Giống như trong số này part on User-Defined Types from OCaml for the Skeptical, tôi muốn sử dụng các loại biến thể để mô tả bộ quần áo, thẻ và mọi thứ.

type suit = Club | Diamond | Heart | Spade 
type value = Jack | Queen | King | Ace | Num of int 
type card = Card of suit * value | Joker 
type hand = card list 

Và sẽ rất tuyệt nếu tôi có thể viết chức năng thông minh compare có thể hiểu các loại biến thể được đặt hàng.

Lý tưởng nhất là tôi muốn viết một cái gì đó như thế:

type suit = Club < Diamond < Heart < Spade 
type value = Num of int < Jack < Queen < King < Ace 
type card = Card of suit * value < Joker 
type hand = card list 

Vì vậy mà khi tôi làm

List.sort Pervasives.compare [Card(Diamond, Num 3); Joker; Card(Spade, Ace); Card(Diamond, Num 2)] 

nó mang lại cho tôi

[Card(Diamond, Num 2); Card(Diamond, Num 3); Card(Spade, Ace); Joker] 

Than ôi, lợi nhuận ocaml mục cấp đầu

[Joker; Card(Spade, Ace); Card(Diamond, Num 2); Card(Diamond, Num 3)] 

(đó là đã khá tốt!)

Về cơ bản tôi muốn có một chức năng compare rằng sẽ mất gợi ý từ cấu trúc khai báo kiểu.

Tôi đã đọc số này article on polymorphic comparethis similar question nhưng tôi không chắc chắn mình có muốn phụ thuộc vào compare_val hay không.

Tôi có thực sự phải viết chức năng so sánh của riêng mình không? Nếu bạn đề nghị tôi viết một, bạn có lời khuyên về cách nó nên được viết, đặc biệt là để giảm số lượng các trường hợp?

P.S .: Tôi chỉ nghe nói về deriving(Ord) trong Haskell ... Có thể là đủ cho tôi để có những bước nhảy vọt ...

+0

Tôi yêu Haskell, nhưng tôi sẽ không chuyển tàu trên OCaml chỉ cho đường 'deriving'. Đặc biệt đối với loại nhỏ này. – jozefg

+0

cũng sẽ tốt nếu Num có thể bị hạn chế từ 1..10 – aneccodeal

+1

@aneccodeal yep, một ngày nào đó chúng ta sẽ nhận được các loại phụ thuộc theo ngôn ngữ chính thống. – paob

Trả lời

8

Có bạn phải. Nhưng bạn có thể bỏ qua nơi so sánh đa hình phù hợp với nhu cầu của bạn. Ví dụ, bạn không cần viết so sánh của bạn cho phù hợp.

Xuất hiện của Haskell (Ord) giống như so sánh đa hình: nếu bạn có thể đặt hàng các nhà thầu theo thứ tự trong tâm trí của bạn, thì bạn có thể lấy được hàm so sánh. Nhưng nó mạnh hơn vì bạn có thể soạn các hàm so sánh tự động và tùy chỉnh. Sự so sánh đa hình của OCaml không thể làm được điều này. Ví dụ,

type t = ... 
let compare_t = .... (* custom comparison for t *) 
type t2 = A of t | B of t | C of t (* I want to write a comparion for t2 now! *) 

Nếu thứ tự so sánh đa hình của các nhà xây dựng A, B và C phù hợp với nhu cầu của bạn, bạn không thể sử dụng nó để so sánh các t2, vì nó không thể gọi sự so sánh tùy chỉnh cho t. Vì vậy, trong trường hợp này, nếu tôi là bạn tôi sẽ viết compare_t2 bằng tay. Đối với ví dụ về thẻ của bạn quá, nó có thể dễ dàng thực hiện trong 3 phút.

Nếu kiểu dữ liệu của bạn rất lớn và bạn phải tự mình viết ra tất cả so sánh bằng tay, bạn có thể tự động tạo các hàm so sánh từ định nghĩa kiểu bằng cách sử dụng CamlP4 và type_conv, giống như bắt nguồn (Ord). Nhưng tôi e rằng không có module type_conv nào cung cấp Ord như thế. Cá nhân tôi chưa bao giờ cảm thấy cần phải có nó.Nó sẽ là một bài tập tốt cho người học P4.

+0

Cảm ơn bạn đã trả lời! Tôi nghĩ rằng tôi sẽ cố gắng viết 'so sánh' cho mỗi loại sau đó. Và nếu mã thực sự quá cồng kềnh, tôi sẽ xem CamlP4. – paob

+0

Nếu bạn không quen thuộc với P4, tôi cảnh báo bạn, bạn nên mong đợi một tháng cho điều này :-) – camlspotter

+0

tốt, đây chỉ là một dự án đồ chơi mà không có thời hạn nào vậy tại sao không =) – paob