Vâng, nó không phải là một phần của tiêu chuẩn Haskell 2010, do đó, nó không được bật theo mặc định và được cung cấp dưới dạng tiện ích mở rộng ngôn ngữ thay thế. Đối với lý do tại sao nó không phải trong tiêu chuẩn, các loại rank-n là khá khó khăn hơn để thực hiện hơn so với các loại đồng bằng hạng 1 tiêu chuẩn Haskell có; họ cũng không cần tất cả những điều đó thường xuyên, vì vậy Ủy ban có thể quyết định không bận tâm với họ vì lý do ngôn ngữ và thực hiện đơn giản.
Tất nhiên, điều đó không có nghĩa là các loại hạng n không hữu ích; chúng có rất nhiều công cụ có giá trị như ST
monad (trong đó cung cấp trạng thái có thể biến đổi cục bộ, hiệu quả như IO
, nơi tất cả những gì bạn có thể làm là sử dụng IORef
s). Nhưng chúng làm tăng thêm một chút phức tạp cho ngôn ngữ và có thể gây ra hành vi lạ khi áp dụng các phép biến đổi mã có vẻ lành tính. Ví dụ: một số trình kiểm tra loại xếp hạng n sẽ cho phép runST (do { ... })
nhưng từ chối runST $ do { ... }
, mặc dù hai biểu thức luôn luôn tương đương mà không có loại xếp hạng n. Xem this SO question để biết ví dụ về hành vi bất ngờ (và đôi khi gây phiền nhiễu) có thể gây ra.
Nếu, như sepp2k hỏi, bạn thay vì hỏi tại sao forall
phải được thêm một cách rõ ràng vào chữ ký để tăng tổng quát, vấn đề là (forall x. x -> f x) -> (a, b) -> (f a, f b)
thực sự là loại hạn chế hơn (x -> f x) -> (a, b) -> (f a, f b)
. Sau đó, bạn có thể chuyển vào bất kỳ chức năng nào của biểu mẫu x -> f x
(đối với bất kỳ f
và x
) nào, nhưng với chức năng cũ, chức năng bạn chuyển vào phải hoạt động cho tất cảx
. Vì vậy, ví dụ, một chức năng của loại String -> IO String
sẽ là một đối số cho phép để chức năng thứ hai, nhưng không phải là đầu tiên; nó phải có kiểu a -> IO a
thay thế. Nó sẽ khá là khó hiểu nếu sau này được tự động biến thành cái cũ! Chúng là hai loại rất khác nhau.
Nó có thể có ý nghĩa hơn với những tiềm ẩn forall
s làm rõ:
forall f x a b. (x -> f x) -> (a, b) -> (f a, f b)
forall f a b. (forall x. x -> f x) -> (a, b) -> (f a, f b)
Bạn có hỏi tại sao phần mở rộng không được bật theo mặc định hay không? -> (fa, fb) 'không được xử lý giống như' (forall x. x -> fx) -> (a, b) -> (fa, fb) '? Nếu đó là sau này, bạn có thể chỉ định logic mà bạn đề xuất trình biên dịch nên quyết định nơi để chèn 'forall's? – sepp2k
Sau này, và tôi sẽ không biết bắt đầu đề xuất bất cứ điều gì ở tất cả về chủ đề này! –
Lưu ý rằng kiểu '(x -> f x) -> (a, b) -> (f a, f b)' là khá vô ích. Hàm không thể áp dụng đối số đầu tiên cho một trong hai phần tử của bộ tuple, do đó kết quả của nó phải là '⊥' hoặc' (⊥, ⊥) '. – hammar