Giả định được đưa ra trong thế giới Tìm hiểu bạn một Haskell khi suy luận loại nào?


18

Câu hỏi này không chủ quan. Một động từ rất cụ thể được sử dụng trong cuốn sách được tham khảo và tôi muốn hiểu ý nghĩa của cụm từ đó là gì, bởi vì tôi sợ tôi hiểu nhầm điều gì đó.

Từ Tìm hiểu bạn một Haskell , đoạn văn sau là đoạn thứ ba và cuối cùng có chứa "chúng tôi giả định *".

data Barry t k p = Barry { yabba :: p, dabba :: t k }  

Và bây giờ chúng tôi muốn làm cho nó một ví dụ Functor. Functormuốn các loại loại * -> *nhưng Barrykhông có vẻ như nó có loại đó. Các loại là Barrygì? Vâng, chúng tôi thấy nó có ba tham số loại, vì vậy nó sẽ được something -> something -> something -> *. Thật an toàn khi nói rằng đó plà một loại cụ thể và do đó có một loại *. Đối với k, chúng tôi giả định *và do đó bằng cách mở rộng, tcó một loại* -> * . Bây giờ, hãy thay thế các loại đó bằng các loại somethingmà chúng tôi đã sử dụng làm trình giữ chỗ và chúng tôi thấy nó có một loại (* -> *) -> * -> * -> *.

Tại sao chúng ta lại giả định bất cứ điều gì? Khi đọc "chúng tôi giả sử X (tức là chúng tôi cho rằng X là đúng)", tôi nghĩ rằng chúng ta cũng nên xem xét trường hợp X là sai. Trong trường hợp cụ thể của ví dụ, không tthể là loại (* -> *) -> *kloại (* -> *)? Nếu đây là trường hợp, bất cứ điều gì tkthực sự là, t kvẫn sẽ là một loại cụ thể, phải không?

Tôi thấy rằng toàn bộ dòng lý luận sau đó được kiểm tra đối với trình biên dịch, nhưng tôi không nghĩ trình biên dịch giả định . Nếu có, tôi muốn biết điều gì, nếu không thì tôi lại sợ rằng tôi thiếu ý nghĩa của đoạn văn.


4
Bạn nói đúng. Thật vậy, chúng ta có thể có k :: Lcho bất kỳ loại nào L, miễn là t :: L -> *. Tuy nhiên, một trình biên dịch ở đây phải chọn một số cụ thể Lhoặc sử dụng một polykind. Một polykind sẽ là tùy chọn chung nhất, nhưng ở đây GHC chọn L = *(Haskell cơ bản không có polykind, chúng phải được bật như một phần mở rộng). Vì nó chọn một cái gì đó khá độc đoán, LYAH sử dụng từ "giả định" (AFAICT).
chi

1
Ok, có thể trình biên dịch giả định sẽ làm tôi bối rối ít nhất là ít hơn chúng ta nghĩ , hoặc hoàn toàn không.
Enrico Maria De Angelis

Câu trả lời:


19

Trong thực tế, trình biên dịch không giả định! Nhưng bạn có thể yêu cầu nó không với phần mở rộng PolyKinds. Bạn có thể đọc về nó chi tiết hơn ở đây . Với phần mở rộng được bật, loại Barrysẽ được forall k. (k -> *) -> k -> * -> *.


-1

Điểm tốt. Tác giả đưa ra một giả định không cần thiết. Có lẽ chỉ để dễ hiểu hơn trong chương Type Foo của anh ấy, nhưng những người như bạn có thể nghi ngờ điều này.

Cả hai t, kplà biến kiểu. Như chúng ta thấy từ yabba :: pnó có thể sống một mình nên nó giống như một hàm hằng, như thể nó là một giá trị thay vì một loại, chữ ký loại sẽ nói Inthoặc Char, bất cứ điều gì ... bạn đặt tên cho nó. Nhưng vì nó là một loại nên chữ ký của nó là loại *.

Tuy nhiên tloại ở đây có một biến loại kđể xây dựng một loại ( dabba :: t k) vì vậy chúng tôi chắc chắn rằng (không có giả định ở đây) tcó một chữ ký loại như * -> *k* .

Một khi chúng ta biết điều này ... Barry t k pchữ ký loại của (* -> *) -> * -> * -> *nó có nghĩa là nó sẽ mất tsau kđó pvà cung cấp cho chúng ta Barryloại.

Chỉnh sửa Hãy chắc chắn đọc bình luận của @ luqui's bên dưới.


7
kkhông bị hạn chế *như bạn tuyên bố đó là trong khi suy luận t. Chúng ta có thể có k :: * -> *t :: (* -> *) -> *, ví dụ. Thêm một trường doo :: k Intvào bản ghi và nó sẽ vượt qua mà không có vấn đề.
luqui

@luqui .. Có bạn đúng ... Tôi sẽ không xóa câu trả lời này vì nhận xét của bạn thực sự đáng để đứng.
Redu
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.