Đâ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 ArrowApplythể 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 ArrowApplyvà Monadcá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 Monadvà 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ì ArrowApplyvà Monadtương đương?
Các ví dụ về sự không tương đương Arrowvà Applicativetà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.