这是我要参考的SO帖子。. 另外,为了不把材料分开,我在那道题中使用了和上边一样的片段。.
它是 众所周知 即 ArrowApply
实例会产生一个Monad,反之亦然。
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))
直到我偶然发现... 岗位 上面提到的,我觉得这个片段是一个合理的证明,证明了等价的 ArrowApply
和 Monad
类。然而,在知道 箭头和应用型其实并不等同。 和下面的片段让我对等价物的完整证明产生了好奇。Monad
和 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
>因此,如果你通过applicative进行往返,你会失去一些功能。如果提供的例子是显而易见的,但是我不明白为什么通过Monad的 "往返 "会保留所有ArrowApply的功能,因为最初我们有一个箭头,它依赖于一些输入(a b c
),但最终,我们会将一个箭头强行放入一个以单元类型为输入类型的包装器中(ArrowMonad (a () b)
).
很明显,我在这里做了一件非常错误的事情,然而我却无法理解到底是什么。
什么是充分证明 ArrowApply
和 Monad
是等价的?
不等价的例子有哪些?Arrow
和 Applicative
占?一个人是否能概括另一个人?
在箭头微积分和范畴理论中,对整个情况的解释是什么?
我既希望得到完整的解释,也希望得到可以帮助自己起草一份合理的证明的提示。
由于最初我们有一个箭头,它取决于一些输入(
a b c
),但最终,我们会将一个箭头强行放入一个以单元类型为输入类型的包装器中(ArrowMonad (a () b)
)
我想这是困惑的核心点,的确是困惑。我喜欢把箭头看成是卡提斯一元论范畴中的多数形态,在这里你不会得到这个,但已经有了 Arrow
类实际上比这更有限制性,这要归功于 arr
- 这给了你一个从 哈斯克 到类别中。但是,有些令人惊讶的是,这也意味着你会得到一个在 其他 方向:任何箭头都可以替换为 功能 其中产生的只是一个微不足道的域的箭头。具体来说。
arrAsFunction :: Arrow k => k x y -> (x -> k () y)
arrAsFunction φ x = φ <<< arr (const x)
好吧,光是这一点就不太接地气--也许我们只是在这里抛弃了一些信息?- 但随着 ArrowApply
这其实是 同构性箭头:你可以通过以下方式找回原来的箭头。
retrieveArrowFromFunction :: ∀ k x y .
ArrowApply k => (x -> k () y) -> k x y
retrieveArrowFromFunction f = arr f' >>> app
where f' :: x -> (k () y, ())
f' x = (f x, ())
......这正是使用的是什么在 Monad (ArrowMonad a)
例子。
所以结果是 arr
通过要求你可以在类别中嵌入任何Haskell函数, 强制要求这个类别基本上可以归结为: 函数,并对结果进行一些包装, IOW类似Kleisli箭头的东西。
查看一些其他的类别理论层次结构,可以看到这是 不 的一个基本特征,但实际上是卡提斯一元分类的一个产物。哈斯克 → k 漏斗。例如 在约束类别中 我严格按照标准班级,以 PreArrow
作为卡提斯一元类,但刻意保留了 "卡提斯一元类"。arr
出,并没有将其具体化为。哈斯克因为那会使该类别的能力过于淡化,导致它几乎等同于 哈斯克-Kleisli。