2017-08-15 17 views
6

Tôi đang xem the documentation cho máy biến áp Reader monadReaderT đơn nguyên.Mục đích của * trong Trình biến đổi đơn vị ReaderT là gì?

Các định nghĩa liên quan là:

newtype ReaderT k r m a :: forall k. * -> (k -> *) -> k -> * 
type Reader r = ReaderT * r Identity 

Tôi không hiểu những gì các * đang làm trong các định nghĩa. Đặc biệt, tôi đang cố gắng lấy một đơn nguyên mới từ ReaderT với IO làm đơn nguyên cơ sở và ràng buộc lớp trên giá trị r.

Tôi không chắc tại sao có đầu vào thứ tư cho ReaderT (k) và những gì Reader đang làm với giá trị đó khi nó đặt * ở vị trí đó.

+6

Note mã nguồn cho 'ReaderT' là' newtype ReaderT rma = ReaderT {runReaderT :: r -> ma} '. 'K' chỉ được tạo ra trong tài liệu của Haddock để nhấn mạnh sự đa dạng của' ReaderT' ('-XPolyKinds' được kích hoạt trong mô-đun nơi nó được định nghĩa). – Alec

+2

"Tôi đang cố gắng lấy một đơn nguyên mới từ ReaderT với IO làm đơn nguyên cơ sở và ràng buộc lớp trên giá trị r" - trong khi điều này có thể gây ra nhiều vấn đề hơn giải quyết (việc đặt ràng buộc vào 'r' giá trị, không phải là dẫn xuất của một kiểu mới từ 'ReaderT' với' m' được khởi tạo thành 'IO') Tôi không thấy lý do tại sao làm điều này sẽ bị cản trở bởi định nghĩa polykinded của' ReaderT'. Như các trạng thái @Alec, tham số 'k' là một tạo phẩm của haddock - trong thực tế, nó hoàn toàn tiềm ẩn, và bạn có thể giả vờ rằng' ReaderT :: (* -> *) -> * -> * '(vì nó làm thực sự có loại đó). – user2407038

+0

@ user2407038 và nicolas Cả hai đều chính xác. Ràng buộc thuộc về và bây giờ được đặt trên một khai báo cá thể không phải là định nghĩa đơn nhất. –

Trả lời

5

* là loại loại với giá trị: nó là viết tắt của những thứ như Int, List Int vv ..

forall k nghĩa k không nhất thiết phải thuộc loại đó. nó là viết tắt của bất kỳ loại nào, được xem như những thứ tĩnh đơn giản mà bạn có thể khai báo và thao tác, nhưng không nhất thiết liên quan đến các giá trị thời gian chạy. Một ví dụ của điều này là khi bạn muốn 'trang trí' một số loại khác với thông tin bổ sung: loại thêu không có lý do để có bất kỳ loại giá trị nào gắn liền với nó, nó là thông tin "thuần túy", với một số loại thêu (thường có giá trị)

Đơn giản hơn ở đây, bạn có thể thấy rằng trong Reader tất cả đều được chuyên dùng để *m chuyên dành riêng cho đơn Identity. Đó là nơi bạn muốn IO đơn vị của mình trở thành.

Đối với các ràng buộc, tốt nhất là không chỉ định nó trong chính loại đó. Khi sử dụng, nơi bạn sử dụng một phương pháp cụ thể gắn liền với typeclass, nó sẽ được thêm vào khi đang bay. Thật vậy, không có lý do nào được viết bằng văn bản mà không sử dụng phương pháp nên được gánh nặng bằng cách yêu cầu người gọi của họ cung cấp nó.

(Trừ khi bạn có một lý do rất tốt để, để suy diễn những trường hợp khác, như trong Dict nơi bạn chụp một nhân chứng typeclass như một giá trị thời gian chạy với một GADT, nhưng điều đó có lẽ không phải những gì bạn muốn làm)

+0

Bạn là chính xác. Ràng buộc thuộc về và bây giờ được đặt trên một khai báo cá thể không phải là định nghĩa đơn nhất. –

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