2011-12-15 26 views
11

Khi sử dụng GHC thông dịch viên tương tác, nó có thể yêu cầu loại suy ra của một biểu thức:GHCi chọn tên cho các biến kiểu như thế nào?

Prelude> :t map 
map :: (a -> b) -> [a] -> [b] 

Dường như phải mất tên của các biến kiểu từ chữ ký kể từ mapdefined như

map :: (a -> b) -> [a] -> [b] 
map _ []  = [] 
map f (x:xs) = f x : map f xs 

trong Prelude. Điều đó làm cho rất nhiều ý nghĩa! Câu hỏi của tôi là: làm thế nào là loại tên biến được chọn khi không có chữ ký được đưa ra?

Một ví dụ sẽ

Prelude> :t map fst 
map fst :: [(b, b1)] -> [b] 

nơi nó chọn tên bb1. Rõ ràng là đổi tên phải diễn ra, nhưng chỉ đơn giản là bắt đầu với a, b ... lẽ ra đã giúp

map fst :: [(a, b)] -> [a] 

thay vào đó, mà tôi thấy hơi dễ đọc hơn.

Trả lời

13

Như tôi đã hiểu, ghci chọn tên theo cùng thứ tự nó xâm nhập vào các loại. Nó sử dụng lược đồ đặt tên như bạn đã đề cập để quyết định tên kiểu kết quả, là [b] vì đó là tên kiểu được chỉ định trong định nghĩa của map. Sau đó, nó quyết định rằng hàm đó là tham số đầu tiên cho số map cũng phải trả về một loại nào đó thuộc loại b.

Biến kiểu còn lại sẽ được đặt tên là biến kiểu cho phần tử thứ hai trong đối số tuple đến fst và một lần nữa, nó nhìn định nghĩa của fst để quyết định tên nào sẽ sử dụng. Định nghĩa của fst :: (a, b) -> a, vì vậy b sẽ là tên được ưa thích tại đây, nhưng kể từ khi b đã được sử dụng, nó gắn thêm 1 để nó trở thành b1.

Tôi nghĩ rằng hệ thống này có lợi thế trong các tình huống mà bạn không đối phó với các loại tùy ý như trường hợp ở đây. Nếu loại quả trông giống như thế này, ví dụ:

castAdd :: (Num n, Num n1, Num n2) => n -> n1 -> n2 

... nó được cho là dễ đọc hơn so:

castAdd :: (Num a, Num b, Num c) => a -> b -> c 

... bởi vì bạn hầu như có thể dựa vào đó n# nghĩa một số loại, vì định nghĩa lớp cho Numclass Num n where ....

CHỈNH SỬA: Có, tôi biết rằng castAdd không thể triển khai, nhưng đó chỉ là ví dụ về loại.

+1

Cảm ơn, đó là một lời giải thích tuyệt vời! Tôi đã không nghĩ đến trường hợp bạn muốn một số 'n' được đổi tên nhưng vẫn liên quan. –

+0

Nó không phải là không thể. (unSafeCoerce hoặc chỉ đơn giản là cũ '_ | _') – PyRulez

Các vấn đề liên quan