我正在阅读有关应用程序并尝试理解它的haskellbook.
在书中,作者提到:
因此,使用Applicative,我们的结构和功能应用为我们的价值观提供了Monoid!
monoid如何连接到applicative?
我一直在阅读关于Haskell Applicative仿函数的理论解释的类别:显然,它们可以在类别理论术语中被解释为松散的闭合函子或松散的monoidal仿函数(取决于你问的人,看起来如此),并且这样做了我对以下内容感到疑惑.
不久之前,我写了一篇论文(与Ilya Sergey和我们的顾问Frank Piessens和Dave Clarke一起),使用Applicative仿函数在DSL中使用"效果递归"的递归原语,主要用于解析器库.我们发现我们需要一些非常特殊的构造函数,看起来它们可能是通用的(某种程度上).总之,我要问的是:下面的一些结构是否与类别理论有某种联系,如果是这样,如何?
请注意,我将写p ? q两个applicative functor的组合p和q.
以下是我们在此过程中需要的基元列表:
afix:效果递归原语.我们真的想要一个看起来像这样的递归原语:
afix :: (p a ? p a) ? p a
Run Code Online (Sandbox Code Playgroud)
然而,对于p我们需要的更复杂的解释,这是无法实现的.相反,我们最终得到以下结果:
afix :: (? q. Applicative q ? p (q a) ? p (q a)) ? p a
Run Code Online (Sandbox Code Playgroud)
显然,在这个参数化量化的应用函子q中包装递归出现的值强制了我们采用固定点的函数中的一种价值效应分离.显然,这足以使我们更复杂的功能发挥作用.
在实现中更深入,我们需要一种看似如下的共同运算符:
coapp0 :: (p a ? p b) ? p (a ? b)
Run Code Online (Sandbox Code Playgroud)
但是,要求将其作为一般操作符p,似乎只会将我们限制在只有琐碎的应用函数p.相反,我们注意到我们可以使用以下内容,这是可实现的:
coapp :: Applicative p ? (? q . Applicative q ? (p ? …Run Code Online (Sandbox Code Playgroud)我试图Monoid从类别理论的角度理解什么,但是我与用来描述它的符号有些混淆。这是维基百科:
在范畴论中,在一个单曲面范畴(C,α,I)中的一个单曲面(或单曲面对象)(M,?,I)是一个具有两个同态的对象M
?:M?M?M称为乘法
?: 一世 ?M称为单位
我对态素表示法感到困惑。为什么二进制运算?是射态符号的一部分?我对态射的理解是,它是一种可以从一种类型映射到另一种类型(域到共域)的函数,例如M ? M。为什么操作?是定义中域的一部分?第二个困惑是关于I。为什么是I域名?根本没有I对象Monoid。它只是对象的中性元素M。
我知道这Monoid是一个具有一个对象,同一性同态和在该对象上定义的二进制运算的类别,但是这种表示法使我认为我不了解某些内容。
被M ? M莫名其妙相关笛卡尔积,因此该射的域定义M x M?
编辑:在数学栈交换上,我的问题得到了非常有帮助的答案。
不久前,我已经学会了Monoidal作为一种替代方式来表示Applicative。Typeclassopedia上有一个有趣的问题:
- (棘手)证明给定你在第一个练习中的实现[
pure并(<*>)用unit和(**)和相反的方式写下来],通常的Applicative规律和上述Monoidal规律是等价的。
以下是这些课程和法律:
-- A note from https://wiki.haskell.org/Typeclassopedia#Alternative_formulation:
-- In this and the following laws, ? refers to isomorphism rather than equality.
-- In particular we consider (x,()) ? x ? ((),x) and ((x,y),z) ? (x,(y,z)).
-- Monoidal.
class Functor f => Monoidal f where
unit :: f ()
(**) :: f a -> f b -> f (a,b)
-- unit ** …Run Code Online (Sandbox Code Playgroud) 我已阅读此问答但不了解类别理论部分。
到目前为止,这是我的推理:当我查看类型时
F (a -> b) -> F a -> F b
(a -> M b) -> M a -> M b
a -> F a
a -> M a
Run Code Online (Sandbox Code Playgroud)
唯一在类型级别类似于幺半群的部分是类型构造函数,即应用/单子上下文:
// binary operation
F -> F -> F
M -> M -> M
// identity element
F
M
Run Code Online (Sandbox Code Playgroud)
所以我会说 applicatives/monads 就其上下文而言是幺半群的,因为它们将两个相同类型的上下文组合成一个。pure/return创建了一个最小上下文,因此我们可以将其视为类似于幺半群的标识元素的标识上下文,它创建了一个“最小值”。
然而,monads/applicatives 在它们的类型参数中不是幺半群的,因为它们包含了从ato的转换b。
我不确定我的推理是否有意义。让我感到困惑的是,一方面是幺半群,另一方面是应用程序/单子以不同的方式组合事物:
Nothing <> (Just "bar") -- Just "bar"
(++) <$> Nothing <*> (Just "bar") -- Nothing …Run Code Online (Sandbox Code Playgroud)