Chữ trong ngôn ngữ chức năng có thể được coi là chức năng từ loại trống không?


7

Cách đây một thời gian, tôi nghĩ về Stack Overflow, tôi đã thấy ai đó nói rằng chữ Haskell có thể được coi là các chức năng không hoạt động trên bất cứ thứ gì. Điều này có ý nghĩa với tôi nhưng tôi nhớ người khác kịch liệt không đồng ý với anh ta.

Nếu tôi hiểu chính xác, tất cả các giá trị trong các kiểu nguyên thủy, hoặc ít nhất là các giá trị trong Bool, là các hàm tạo kiểu và các hàm tạo kiểu là một loại hàm đặc biệt trong kiểu. Vì các giá trị như 2.87, Truehoặc 'f'không có bất kỳ tham số nào được truyền cho chúng, có vẻ như nó sẽ không ảnh hưởng đến ngữ nghĩa của ngôn ngữ cho dù bạn nghĩ chúng giống như các thành phần thuộc loại của chúng hoặc một hàm từ loại không chứa gì vào loại của chúng luôn luôn trả về giá trị của họ. Có điều gì sai khi nghĩ về chữ theo cách này?


3
Bạn có nghĩa là các chức năng từ loại đơn vị (tức là bộ dữ liệu trống)? Trong trường hợp này là có.
gallais

1
@gallais À đúng rồi, tôi đã suy nghĩ về nó từ góc độ của một lý thuyết loại phụ thuộc trong đó đơn vị có một yếu tố. Nhưng điều này có ý nghĩa, cảm ơn, bạn nên biến điều này thành một câu trả lời.
Anon Ymous

Câu trả lời:


10

Hãy bắt đầu bằng một ngôn ngữ tổng thể như Agda. Sau đó, như gallais tuyên bố, điều này chỉ có ý nghĩa nếu theo "loại trống", bạn có nghĩa là loại đơn vị, tức là bộ dữ liệu 0-ary, có chính xác một giá trị. Loại trống có thể được coi là loại tổng 0 trường hợp và không có giá trị nào cả. Trong Agda, bạn có thể dễ dàng chứng minh rằng nó Unit -> Alà đẳng cấu A. Theo nghĩa đó, bạn có thể coi chúng giống nhau, mặc dù chúng vẫn không giống nhau theo nghĩa đen. Tôi không thể, ví dụ, làm một phân tích trường hợp trên Unit -> Boolvà tôi cũng không thể áp dụng True : Boolcho bất cứ điều gì như là một chức năng.

Câu chuyện cho Haskell khá khác biệt. () -> AAlà các loại không đẳng cấu. Đặc biệt, () -> ()có bốn giá trị, trong khi ()chỉ có 2. Bốn observationally biệt giá trị undefined, \_ -> undefined, \x -> x, \_ -> (). Vì vậy, ()thực sự không phải là một loại đơn vị, theo nghĩa là có chính xác một chức năng (). (Trong Agda, mặt khác, chúng ta có thể chứng minh rằng nếu x : Unity : Unit, thì chúng bằng nhau [theo định nghĩa vì vậy nếu chúng ta xác định Unitbằng recordcú pháp trái ngược với datacú pháp]. Điều đó có nghĩa là, Unitchỉ có một giá trị. UnitA -> Unitlà đẳng cấu cho bất kỳ A.)

Trong thực tế, một loại "trống" như Voidđược định nghĩa data Voidgần giống như một loại đơn vị theo nghĩa này. Voidchỉ có một giá trị, nhưng Void -> Voidvẫn có hai. Trong thực tế, mọi loại hàm A -> B, có ít nhất hai giá trị riêng biệt quan sát được, đó là undefined\_ -> undefined. Do đó, Haskell không có đơn vị thực sự hoặc loại khoảng trống.

Rất nhiều điều này là do Haskell là một ngôn ngữ không nghiêm ngặt và bị bực tức bởi sự tồn tại của seq(và tương đương của nó). Ví dụ, sự khác biệt giữa undefined\_ -> undefinedchỉ có thể được nhìn thấy với seq. Nếu chúng ta loại bỏ seqvà tương đương với Haskell, thì Voidsẽ phục vụ như một loại đơn vị, tuy nhiên, trớ trêu thay, vẫn không phải là một loại trống.

Thông thường, khi mọi người nói về những điều như vậy trong Haskell, họ ngầm giả vờ rằng Haskell là một ngôn ngữ cư xử tốt hơn nó. Đó là, họ cho rằng đáy không tồn tại cho mục đích của họ, tức là bạn đang làm việc trong một ngôn ngữ tổng thể như Agda. Đối với mục đích thiết kế mã của bạn, điều này thường là đầy đủ; nó không phổ biến mà chúng ta quan tâm hoặc mong đợi đáy. Những khác biệt này có thể trở nên quan trọng nếu chúng ta đang làm một cái gì đó như lập trình vòng tròn hoặc nếu đảm bảo an toàn cho chương trình của chúng tôi dựa vào các thuộc tính này, ví dụ: một hàm không bao giờ có thể được gọi nếu nó có kiểu trống như miền của nó.


1
Vì tò mò, Haskell có nơi nào chính thức xác định khái niệm về một giá trị (trái ngược với một thuật ngữ) không?
Andrej Bauer

1
@AndrejBauer Như bạn đã biết, Haskell không có ngữ nghĩa chính thức, vì vậy không có định nghĩa chính thức về giá trị. Báo cáo Haskell sử dụng từ " giá trị " nhưng không thực sự định nghĩa nó ngoại trừ một phần trong việc chuyển như giải thích các biểu thức. Ví dụ, nó nói rõ ràng rằng lỗi / không kết thúc là giá trị .
Derek Elkins rời SE

Vâng, tôi chỉ muốn trêu chọc Haskellites về việc thiếu một sự khiếm khuyết thực sự của ngôn ngữ.
Andrej Bauer

@AndrejBauer Điều đó thực sự đáng tiếc. Dân gian muốn rằng có ngữ nghĩa của một số mảnh Haskell, nhưng không có định nghĩa thống nhất duy nhất. Có lẽ nó đã phát triển quá nhiều để được xử lý với một nỗ lực hợp lý: những thứ như ST, ép buộc an toàn eqT, GADT, gia đình kiểu, kiểu chữ rất chung chung (không mạch lạc?!), V.v ... trông hơi cồng kềnh để xử lý. Thậm chí có thể có một vấn đề hoàn vốn đầu tư ở đây: ngay cả khi một người có thể (?) Sản xuất một ngữ nghĩa chính thức với chi phí lớn, liệu nó có ảnh hưởng lớn tương ứng không? Chắc là không. Và sau 2 năm, một phần mở rộng GHC mới sẽ phá vỡ nó ... :-(
chi

1
@chi Trên thực tế, dự án K Framework nói chung trông khá thú vị và có một dự án đang hoạt động để cung cấp công thức cơ giới hóa GHC Core trong đó. Công việc áp dụng K Framework cho C, Java và JavaScript có vẻ khá hứa hẹn và ý tưởng đằng sau K Framework (và Logic Logic phù hợp ) là tăng ROI về ngữ nghĩa cơ giới hóa bằng cách tạo ra nhiều công cụ từ một ngữ nghĩa chung.
Derek Elkins rời SE
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.