我一直在阅读关于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)我已经实现了这样的地图类型类型
type family MapT (t :: * -> *) (e::[*])
type instance MapT t '[] = '[]
type instance MapT t (a ': as) = (t a) ': (MapT t as)
Run Code Online (Sandbox Code Playgroud)
它适用于类型构造函数:
type MList = MapT Maybe '[Int, String]
Run Code Online (Sandbox Code Playgroud)
给
'[Maybe Int, Maybe String]
Run Code Online (Sandbox Code Playgroud)
但是,我试试
type M a = Maybe a
type MList' = MapT M '[Int, String]
Run Code Online (Sandbox Code Playgroud)
它不起作用.
我也试过打字
type family M a
type instance M a = Maybe a
Run Code Online (Sandbox Code Playgroud)
但它仍然无效
`Type synonym `M` should have 1 argument.
Run Code Online (Sandbox Code Playgroud)
有没有办法解决这个问题,而无需创建新的数据类型(或新类型)?