Hàm ML loại 'a ->' b


19

Giáo sư của chúng tôi yêu cầu chúng tôi nghĩ về một chức năng trong OCaml có loại

'a -> 'b

tức là một hàm của một đối số có thể là bất cứ thứ gì và có thể trả về một thứ khác.

Tôi đã nghĩ đến việc sử dụng raisetrong một hàm mà bỏ qua đối số của nó:

let f x = raise Exit

Nhưng giáo sư cho biết có một giải pháp không yêu cầu bất kỳ chức năng nào trong thư viện chuẩn. Tôi bối rối: làm thế nào bạn có thể thực hiện 'bnếu bạn không có một ở nơi đầu tiên?

Tôi đang hỏi ở đây chứ không phải trên Stack Overflow vì tôi muốn hiểu những gì đang diễn ra, tôi không muốn chỉ xem một chương trình mà không có lời giải thích.


2
Vui lòng nhắm mục tiêu chương trình học tập của sinh viên CS101 trong câu trả lời của bạn, chứ không phải nhà lý thuyết loại mà câu trả lời của bạn có thể truyền cảm hứng cho anh ta sau này trở thành.
Gilles 'SO- ngừng trở nên xấu xa'

Sẽ hữu ích nếu bạn giải thích cách bạn tìm ra nó raisesẽ hoạt động, vì vậy chúng tôi biết cách tốt nhất để giải thích lý do tại sao giải pháp mà prof của bạn đang tìm kiếm (sẽ hoạt động với cùng lý do raisehoạt động).
sepp2k

@ sepp2k raise : exn -> 'ađể tôi có thể nhận được giá trị trả về, tôi chỉ cần bỏ qua đối số.
Gilles 'SO- ngừng trở thành ác quỷ'


Câu trả lời:


18

Bộ xương là let f x = BODY. Trong BODY, bạn phải sử dụng x chỉ theo những cách chung (ví dụ: không gửi nó đến một hàm mong đợi số nguyên) và bạn phải trả về giá trị của bất kỳ loại nào khác. Nhưng làm thế nào phần sau có thể đúng? Cách duy nhất để thỏa mãn câu lệnh "cho tất cả các loại 'b, giá trị được trả về là giá trị của loại 'b" là đảm bảo hàm không trả về. Có chính xác hai khả năng: lỗi CƠ THỂ hoặc không chấm dứt. Các raiselỗi chức năng , sau đây không chấm dứt:

let rec f x = f x

19

Đầu tiên, một số nhận xét. Chỉ sử dụng phép tính lambda đã gõ, không thể có được 'a -> 'bvì hệ thống gõ tương ứng (thông qua cấu trúc đẳng cấu Curry Howard ) cho logic logic trực giác và công thức tương ứng A → Bkhông phải là phương pháp luận.

Phần mở rộng khác như các bộ và matchings / điều kiện vẫn duy trì một số loại sản phẩm lý thống nhất bổ sung *tương ứng với các liên kết logic , và các loại tiền |đó tương ứng với các hoặc . Một lần nữa, đừng hy vọng họ sản xuất 'a -> 'bloại đó , vì nó sẽ cho phép người ta chứng minh một số công thức không phải là tautology.

Vì vậy, cơ hội duy nhất của bạn đang sử dụng các công trình khác mà thoát khỏi logic như raise(nhưng bạn không được phép để trong trường hợp này) ... hay let rec! Đệ quy cho phép xây dựng các chương trình không bao giờ chấm dứt và kết quả của chúng có thể được cung cấp một kiểu trả về tùy ý vì chúng sẽ không bao giờ được tạo ra. Bây giờ nếu bạn nghĩ về hàm không kết thúc tầm thường nhất (hàm tự gọi trực tiếp để trả về kết quả):

let rec f x = f x

Bạn sẽ nhận thấy rằng loại của nó là chính xác 'a -> 'b: bất kể đối số được cung cấp là gì, kết quả (sẽ không bao giờ được tính toán) có thể được coi là có bất kỳ loại nào.

Tất nhiên đây fkhông phải là một chức năng thú vị, nhưng đó là điểm chính. Trong OCaml, bất kỳ hàm nào có kiểu không giống như một công thức hợp lệ là một hàm đáng ngờ.


Người hỏi không hiểu một từ trong hai đoạn đầu tiên của bạn, nhưng tôi thích câu của bạn, kết quả của họ có thể được đưa ra một kiểu trả về tùy ý vì chúng sẽ không bao giờ được tạo ra.
Gilles 'SO- ngừng trở thành ác quỷ'

1

Sử dụng một trình biên dịch nguyên thủy, bạn có thể viết điều này:

external magic: 'a -> 'b = "%identity"

(và thực sự phân phối trình biên dịch cung cấp điều này, mặc dù không phải là một phần của ngôn ngữ). Đây là một danh tính không an toàn đúc.

Giáo sư của bạn gần như chắc chắn không muốn điều này. Tuy nhiên, đây cũng là chức năng hữu ích duy nhất với loại 'a -> 'bmà tôi biết và thực sự nó được sử dụng trong bản phân phối OCaml.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.