Điều này không đánh máy vì lớp Adjunction
chỉ đại diện cho một tập hợp nhỏ các điều chỉnh, trong đó cả hai hàm đều là endofunctor trên Hask .
Hóa ra, đây không phải là trường hợp của sự điều chỉnh (<-:) r -| (<-:) r
. Có hai functor tinh tế khác nhau ở đây:
f = (<-:) r
, functor từ Hask đến Op (Hask) (loại đối lập của Hask, đôi khi cũng được ký hiệu là Hask ^ op)
g = (<-:) r
, functor từ Op (Hask) đến Hask
Cụ thể, counit
nên là một phép biến đổi tự nhiên trong danh mục Op (Hask), giúp lật các mũi tên xung quanh:
unit :: a -> g (f a)
counit :: f (g a) <-: a
Trong thực tế, counit
trùng với unit
trong điều chỉnh này.
Để nắm bắt điều này một cách chính xác, chúng ta cần khái quát hóa các lớp Functor
và Adjunction
để chúng ta có thể mô hình hóa các điều chỉnh giữa các loại khác nhau:
class Exofunctor c d f where
exomap :: c a b -> d (f a) (f b)
class
(Exofunctor d c f, Exofunctor c d g) =>
Adjunction
(c :: k -> k -> Type)
(d :: h -> h -> Type)
(f :: h -> k)
(g :: k -> h) where
unit :: d a (g (f a))
counit :: c (f (g a)) a
Sau đó, chúng tôi nhận được một lần nữa đó Compose
là một đơn nguyên (và một comonad nếu chúng ta lật điều chỉnh):
newtype Compose f g a = Compose { unCompose :: f (g a) }
adjReturn :: forall c f g a. Adjunction c (->) f g => a -> Compose g f a
adjReturn = Compose . unit @_ @_ @c @(->)
adjJoin :: forall c f g a. Adjunction c (->) f g => Compose g f (Compose g f a) -> Compose g f a
adjJoin = Compose . exomap (counit @_ @_ @c @(->)) . (exomap . exomap @(->) @c) unCompose . unCompose
và Cont
chỉ đơn thuần là một trường hợp đặc biệt về điều đó:
type Cont r = Compose ((<-:) r) ((<-:) r)
Xem thêm ý chính này để biết thêm chi tiết: https://gist.github.com/Lysxia/beb6f9df9777bbf56fe5b42de04e6c64
Tôi đã đọc được rằng với một cặp bổ trợ, chúng tạo thành một Monad & Comonad độc đáo nhưng được cung cấp một Monad, nó có thể được nhân tố thành nhiều yếu tố. Có ví dụ nào về điều này?
Các yếu tố nói chung không phải là duy nhất. Khi bạn đã khái quát các điều chỉnh như trên, thì ít nhất bạn có thể tính bất kỳ đơn nguyên nào M
dưới dạng điều chỉnh giữa danh mục Kleisli và danh mục cơ sở của nó (trong trường hợp này là Hask).
Every monad M defines an adjunction
F -| G
where
F : (->) -> Kleisli M
: Type -> Type -- Types are the objects of both categories (->) and Kleisli m.
-- The left adjoint F maps each object to itself.
: (a -> b) -> (a -> M b) -- The morphism mapping uses return.
G : Kleisli M -> (->)
: Type -> Type -- The right adjoint G maps each object a to m a
: (a -> M b) -> (M a -> M b) -- This is (=<<)
Tôi không biết liệu đơn nguyên tiếp tục có tương ứng với một sự điều chỉnh giữa các endofunctor trên Hask hay không.
Xem thêm bài viết nCatLab về các đơn nguyên: https://ncatlab.org/nlab/show/monad#RelationToAdjiftsAndMonadicity
Liên quan đến điều chỉnh và đơn điệu
Mọi điều chỉnh (L R) tạo ra một R∘L đơn âm và một L∘R đơn âm. Nhìn chung, có nhiều hơn một điều chỉnh làm phát sinh một đơn vị nhất định theo cách này, trên thực tế có một danh mục các điều chỉnh cho một đơn vị nhất định. Đối tượng ban đầu trong thể loại đó là sự điều chỉnh đối với thể loại Kleisli của đơn nguyên và đối tượng đầu cuối là đối với thể loại đại số Eilenberg-Moore. (ví dụ Borceux, quyển 2, prop. 4.2.2) Cái sau được gọi là điều chỉnh đơn âm.