Đây là bài viết SO tôi sẽ đề cập đến . Ngoài ra, tôi sẽ sử dụng các đoạn giống như OP trong câu hỏi đó để không tách các tài liệu .
Người ta biết rằng một ArrowApply
thể hiện mang lại một Monad và ngược lại:
newtype ArrowMonad a b = ArrowMonad (a () b)
instance Arrow a => Functor (ArrowMonad a) where
fmap f (ArrowMonad m) = ArrowMonad $ m >>> arr f
instance Arrow a => Applicative (ArrowMonad a) where
pure x = ArrowMonad (arr (const x))
ArrowMonad f <*> ArrowMonad x = ArrowMonad (f &&& x >>> arr (uncurry id))
instance ArrowApply a => Monad (ArrowMonad a) where
ArrowMonad m >>= f = ArrowMonad $
m >>> arr (\x -> let ArrowMonad h = f x in (h, ())) >>> app
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
Và cho đến khi tôi tình cờ thấy bài đăng được giới thiệu ở trên, tôi cảm thấy rằng đoạn trích này là một bằng chứng xác thực cho sự tương đương ArrowApply
và Monad
các lớp. Tuy nhiên, trên thực tế , có kiến thức rằng Mũi tên và Ứng dụng không thực sự tương đương và đoạn trích sau đây khiến tôi tò mò về bằng chứng đầy đủ về sự tương đương của Monad
và ArrowApply
:
newtype Arrplicative arr o a = Arrplicative{ runArrplicative :: arr o a }
instance (Arrow arr) => Functor (Arrplicative arr o) where
fmap f = Arrplicative . (arr f .) . runArrplicative
instance (Arrow arr) => Applicative (Arrplicative arr o) where
pure = Arrplicative . arr . const
Arrplicative af <*> Arrplicative ax = Arrplicative $
arr (uncurry ($)) . (af &&& ax)
newtype Applicarrow f a b = Applicarrow{ runApplicarrow :: f (a -> b) }
instance (Applicative f) => Category (Applicarrow f) where
id = Applicarrow $ pure id
Applicarrow g . Applicarrow f = Applicarrow $ (.) <$> g <*> f
instance (Applicative f) => Arrow (Applicarrow f) where
arr = Applicarrow . pure
first (Applicarrow f) = Applicarrow $ first <$> f
> Vì vậy, nếu bạn đi vòng qua ứng dụng, bạn sẽ mất một số tính năng.
Rõ ràng là nếu các ví dụ được cung cấp, nhưng tôi không nắm bắt được cách "vấp vòng" thông qua Monad bảo tồn tất cả các tính năng của ArrowApply vì ban đầu chúng tôi có một mũi tên phụ thuộc vào một số đầu vào ( a b c
) nhưng cuối cùng, chúng tôi kết thúc bằng một mũi tên buộc vào một trình bao bọc có loại đơn vị là loại đầu vào ( ArrowMonad (a () b)
).
Rõ ràng là tôi đang làm điều gì đó cực kỳ sai ở đây, nhưng tôi không thể hiểu chính xác điều gì.
Bằng chứng đầy đủ đó là gì ArrowApply
và Monad
tương đương?
Các ví dụ về sự không tương đương Arrow
và Applicative
tài khoản cho những gì? Có một cái chung chung khác?
Giải thích toàn bộ tình huống đó trong tính toán mũi tên và lý thuyết thể loại là gì?
Tôi sẽ đánh giá cao cả những lời giải thích đầy đủ và những lời khuyên có thể giúp người ta tự đưa ra một bằng chứng chính đáng.