2012-01-07 30 views

Trả lời

30

Sẽ dễ dàng hơn nhiều nếu bạn xem định nghĩa của StoreT itself.

Bạn có thể coi đó là "địa điểm" trong cấu trúc lớn hơn. Ví dụ: lens chỉ là a -> Store b a; bạn nhận được giá trị của trường b và một hàm b -> a để đặt giá trị mới trở lại ngữ cảnh lớn hơn.

Xét nó trong hình thức đơn giản, không biến thế của nó:

data Store s a = Store (s -> a) s 

instance Functor (Store s) where 
    fmap f (Store g s) = Store (f . g) s 

instance Extend (Store s) where 
    duplicate (Store f s) = Store (Store f) s 

instance Comonad (Store s) where 
    extract (Store f s) = f s 

tức duplicate thay đổi s -> a thành một s -> Store s a mà chỉ trả về "cập nhật" diễn ra sau khi thay thế các giá trị, và extract phục hồi bản gốc một bằng cách đặt giá trị trở lại cấu trúc lớn hơn.

Theo như mối quan hệ của nó đối với Nhà nước đi, bạn có thể nhìn vào nó như thế này:

type State s a = s -> (a, s) 
type Store s a = (s -> a, s) 
+15

Chỉ cần mở rộng kết nối giữa Nhà nước và Cửa hàng, tất cả các đơn vị phát sinh từ thành phần của các functors phụ. Nó thường được biết rằng các functors '(r -> _)' (aka Reader) và '(_, r)' (cũng làm việc lộn xộn, nhưng không phù hợp với cách trình bày thông thường của State trong Haskell, và không thể là một Ví dụ Functor trong Haskell) là adjoint, và nếu bạn soạn chúng một cách ('s -> (_, s)') bạn sẽ nhận được một đơn nguyên, và nếu bạn soạn chúng theo cách khác ('(s -> _, s) ') bạn sẽ nhận được một comonad. – copumpkin

+0

@copumpkin: Đó là '(_, r)' không thể là Functor, phải không? '(r, _)' chỉ là 'instance Functor ((,) r)'. – ehird

+0

Vâng, xin lỗi, tôi đã chỉnh sửa sai ý kiến ​​cha mẹ đó :) – copumpkin

33

Với định nghĩa sau đây của cửa hàng,

data Store s a = Store { peek :: s -> a, pos :: s } 

Tôi thích nghĩ về một Store như một nhà kho lớn chứa đầy các giá trị loại a. Mỗi giá trị loại a được bỏ vào vị trí được gắn nhãn bằng giá trị chỉ mục của loại s. Cuối cùng có một xe nâng đỗ tại vị trí pos. Xe nâng có thể được sử dụng để extract giá trị loại a từ cửa hàng bằng cách kéo giá trị ra khỏi vị trí đỗ xe. Bạn có thể sử dụng seek để chuyển xe nâng đến vị trí tuyệt đối mới hoặc sử dụng seeks để di chuyển xe nâng đến vị trí tương đối mới. Để cập nhật tất cả các giá trị của việc sử dụng cửa hàng fmap. Cuối cùng, extend f tương tự như fmap ngoại trừ thay vì f :: a -> a', chúng tôi có f :: Store s a -> a' cho phép chức năng cập nhật không chỉ có quyền truy cập vào giá trị đang được cập nhật mà còn cấp quyền truy cập vào vị trí của giá trị và quyền truy cập vào giá trị của mọi thứ khác trong cửa hàng. Nói cách khác, extend sử dụng giá trị cộng với ngữ cảnh xung quanh để thực hiện cập nhật.

Tương tự tính toán sẽ là suy nghĩ của một đĩa cứng lớn với các giá trị được lưu trữ ở các vị trí khác nhau, cộng với một đầu đậu ở một vị trí cụ thể.

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