Trong Haskell, sự khác biệt giữa toán tử liên kết và toán tử Kleisli là gì và chúng có liên quan như thế nào?


Câu trả lời 1:

Tôi giả sử rằng:

  • 'Toán tử liên kết' là liên kết đơn âm: >> = 'Toán tử Kleisli' là thành phần của mũi tên Kleisli (còn gọi là 'cá'):> =>

Thứ nhất, một mũi tên Kleisli là một chức năng của mẫu

a -> mb

Đối với một số đơn nguyên m. Chúng ta có thể kết hợp hai mũi tên của biểu mẫu này để tạo thành phần thứ ba, giống như thành phần hàm thông thường (ngoại trừ thứ tự của các đối số). Đây là toán tử thành phần mũi tên Kleisli (còn gọi là 'cá'):

(> =>) :: (a -> mb) - mũi tên Kleisli đầu tiên -> (b -> mc) - mũi tên Kleisli thứ hai -> (a -> mc)

Nếu chúng ta chọn định nghĩa các đơn nguyên có trả về và tham gia, thì chúng ta có thể viết cái này là

(f> => g) x = tham gia (g <$> fx)

bởi vì

(g <$> fx) :: m (mc)

Trong đó <$> là biến thể infix của fmap. Trong ký hiệu không có điểm:

f> => g = tham gia. fmap g. f

(Nhớ lại rằng trả về kết thúc một giá trị thuần túy và tham gia sẽ loại bỏ một mức lồng nhau (m (ma) -> ma).)

Toán tử liên kết áp dụng một mũi tên Kleisli cho một giá trị đơn trị:

(>> =) :: ma - giá trị đơn âm -> (a -> mb) - mũi tên Kleisli -> mb

Nó cũng có thể được định nghĩa dưới dạng trả lại và tham gia:

mx >> = f = tham gia (f <$> mx)

Tương tự, bởi vì

(f <$> mx) :: m (mb)

Trên thực tế, chúng ta có thể định nghĩa ràng buộc về mặt 'cá' và ngược lại:

mx >> = f = (const mx> => f) () (f> => g) x = fx >> = g