Comonad là gì và chúng hữu ích như thế nào?


16

Gần đây tôi đã phủ nhận kiến ​​thức của mình về cách thức hoạt động của Monads. Tôi cũng đã được giới thiệu về khái niệm 'Comonad' , được mô tả là đối ngẫu ngược của một đơn nguyên . Tuy nhiên, tôi không thể quấn đầu xung quanh nó.

Để hiểu về Monads, tôi tự tạo ra sự tương đồng cho chính mình:

Monads có thể được coi là "bản thiết kế để xây dựng các băng chuyền biểu thức".

Để xác định Monad mới (một loại hệ thống băng chuyền mới), bạn cần xác định:

  1. Một cách để đặt một cái gì đó lên băng chuyền, ví dụ: 'bắt đầu' một băng chuyền. (Được gọi là unithoặc return)
  2. Một cách để kết nối một máy (một biểu thức) sẽ là một phần của băng chuyền với băng chuyền. (Được biết là joinhoặc bindhoặc >>=).

(Có một hoạt động thứ ba lấy băng chuyền hiện tại, ném nội dung của nó đi và bắt đầu một băng chuyền mới được gọi là >>, nhưng nó rất hiếm khi được sử dụng.)

Để các máy móc và băng tải hoạt động chính xác với nhau, bạn sẽ cần đảm bảo rằng:

  1. Nếu bạn đặt một cái gì đó lên băng chuyền và đưa nó qua máy, đầu ra sẽ giống như khi bạn đưa nó qua máy bằng tay. (Danh tính bên trái)
  2. Nếu bạn muốn đặt một băng chuyền ở giữa một băng chuyền đã có sẵn, bạn không nên kết thúc với một băng chuyền có một băng chuyền trên đầu, mà là một băng chuyền dài hơn, duy nhất. (Danh tính đúng)
  3. Sẽ không thành vấn đề đối với đầu ra nếu bạn sử dụng máy A theo cách thủ công, sau đó chuyển kết quả qua BC được kết nối băng tải hoặc nếu bạn sử dụng AB kết nối băng tải và sau đó chuyển kết quả qua C. Nói cách khác: (a >> = b) >> = c) phải giống với (a >> = (b >> = c)) (Tính kết hợp)

Băng tải đơn giản nhất sẽ là băng tải chỉ lấy đầu vào và luôn tiếp tục biểu thức tiếp theo. Đây là những gì một 'đường ống' là.

Một khả năng khác, là chỉ cho nó đi qua máy tiếp theo nếu một số điều kiện được đáp ứng cho giá trị. Điều này có nghĩa là nếu tại một số biểu thức ở giữa, giá trị thay đổi thành thứ không còn được phép thì phần còn lại của biểu thức sẽ bị bỏ qua. Đây là những gì đơn vị 'Có thể' làm trong Haskell.

Bạn cũng có thể thực hiện các quy tắc sao chép / thay đổi có điều kiện ưa thích khác trên các giá trị trước hoặc sau khi bạn chuyển chúng vào máy. Một ví dụ: Trình phân tích cú pháp (Ở đây, nếu một biểu thức trả về kết quả 'thất bại', giá trị từ trước khi biểu thức được sử dụng làm đầu ra).

Tất nhiên sự tương tự là không hoàn hảo, nhưng tôi hy vọng nó mang lại một đại diện ổn về cách thức hoạt động của các đơn vị.

Tuy nhiên, tôi gặp rất nhiều khó khăn để biến sự tương tự này lên đầu để hiểu về Comonads. Tôi biết từ một lượng nhỏ thông tin tôi đã tìm thấy trên internet mà Comonad định nghĩa:

  • extract, Đó là loại mặt trái của return, đó là, phải mất một giá trị ra của một Comonad.
  • duplicate, đó là loại nghịch đảo của join, nghĩa là, nó tạo ra hai Comonad từ một cái duy nhất.

Nhưng làm thế nào một Comonad có thể được khởi tạo nếu chúng ta chỉ có thể trích xuất từ ​​chúng hoặc sao chép chúng? Và làm thế nào chúng thực sự có thể được sử dụng? Tôi đã xem dự án rất tuyệt vời nàynói về nó (điều mà tôi không may hiểu rất ít), nhưng tôi không chắc phần chính xác được cung cấp bởi Comonad.

Comonad là gì? Chúng hữu ích cho việc gì? Làm thế nào chúng có thể được sử dụng? Chúng có ăn được không?


2
"làm thế nào một Comonad có thể được khởi tạo nếu chúng ta chỉ có thể trích xuất từ ​​chúng hoặc sao chép chúng?" - Tôi sẽ trả lời câu hỏi của bạn bằng một câu hỏi: làm thế nào một Monad có thể được tiêu thụ nếu bạn chỉ có thể nâng giá trị vào chúng và tính toán theo trình tự?
Benjamin Hodgson

1
"Máy ở cuối băng chuyền" (bên cạnh: Tôi không tìm thấy sự tương tự tất cả những gì hữu ích khi nói về các IOđơn nguyên ) của đơn vị là hệ thống thời gian chạy Haskell, gọi ra main. Tất nhiên cũng có unsafePerformIO. Nếu bạn muốn nghĩ về Maybeđơn nguyên là có một "cỗ máy ở cuối băng chuyền", bạn có thể sử dụng maybe.
Benjamin Hodgson

1
Nhưng, giải thích lại, khi bạn muốn tạo ra một giá trị comonadic khi bắt đầu một chuỗi cobindứng dụng, phải có một số chức năng nào đó hữu ích với biểu diễn bên trong của comonad của bạn.
Benjamin Hodgson

2
ví dụ cụ thể của comonad hoặc monad rõ ràng có thể có nhiều chức năng hơn yêu cầu chỉ để thực hiện các kiểu chữ
jk.

2
Không phải là điều này sẽ rất hữu ích nếu bạn không tiếp cận câu hỏi này từ phía loại-lý thuyết / toán học, nhưng tôi muốn chỉ ra rằng một comonad không phải là nghịch đảo mà là kép của một đơn nguyên.
Jörg W Mittag

Câu trả lời:


11

Một comonad, giống như một đơn nguyên, một cấu trúc toán học trong lý thuyết thể loại. Tiền tố rất phổ biến ở đó để biểu thị "nghịch đảo" khi bạn đặt nó (mặc dù tôi không nghĩ các nhà toán học thuần túy đồng ý về việc lựa chọn từ).

Trong lý thuyết thể loại categories, có một thời gian ngắn đặt một bộ sưu tập objects(thuộc bất kỳ loại hoặc tính chất nào, cấu trúc bên trong không liên quan) và một số arrowsgiữa các đối tượng này. Để một cái gì đó trở thành một thể loại, các mũi tên phải tuân theo một số luật (nhận dạng trái / phải và sự kết hợp), nhưng điều đó không thực sự quan trọng ở đây.

Bây giờ, lý thuyết thể loại là cả rất trừu tượng / khó để mò mẫm và rộng lớn. Phải mất rất nhiều thời gian để trải qua tất cả (và tôi chưa nghiên cứu chính thức, tôi chỉ biết một số điều cơ bản), nhưng có một khái niệm được sử dụng được gọi là a dual. Về cơ bản, đối với mọi danh mục bạn có thể xây dựng một opposite categorychỉ bằng cách làm cùng một việc nhưng "đảo ngược tất cả các mũi tên". Đây là một định nghĩa rất ngây thơ nhưng thật khó để cố gắng tóm tắt. Nguyên tắc kép của một thứ gì đó trong danh mục C về cơ bản là giống nhau trong danh mục C_op đối diện (bạn đang đau đầu chưa?)

Dù sao, nếu bạn có một đơn vị trên một danh mục nào đó (và ví dụ một danh mục có thể là một danh mục trong đó các đối tượng là các loại trong ngôn ngữ lập trình và các mũi tên là các chức năng giữa các loại), thì về cơ bản là một comonad 'Đã đảo ngược tất cả các mũi tên (giống như đảo ngược chữ ký hàm trong trường hợp này).

Một hơn "thực hành" mô tả (mặc dù thực hành không SUPER) có thể được tìm thấy trong này thảo luận giữa Erik Meijer và Brian Beckman, nơi họ đang thảo luận khái niệm nhị nguyên và làm thế nào Erik đi về "đảo ngược các mũi tên" cho IEnumerable<T>trong C # khi tạo khung phản ứng và IObservable<T>(theo như tôi có thể nói, và tôi rất vui khi được sửa chữa, về cơ bản là một ví dụ danh sách comonad).

Một ví dụ thực tế khác về các comonad được đề cập trong video là Task<T>loại trong .NET, trong đó Task<U> ContinueWith<U>(Func<Task<T>, U>)sẽ là kép của bind(hoặc SelectManynhư được gọi trong C #)


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.