首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从Data.Data.Data理解gfoldl的类型签名

从Data.Data.Data理解gfoldl的类型签名
EN

Stack Overflow用户
提问于 2015-03-18 10:48:24
回答 1查看 629关注 0票数 15

Data将其核心功能之一gfoldl定义为

代码语言:javascript
运行
复制
gfoldl
  :: (Data a)
  => (forall d b. Data d => c (d -> b) -> d -> c b) 
  -> (forall g. g -> c g)   
  -> a  
  -> c a

cc (d -> b)在其中的目的是什么?为什么不只是一个常规的折叠,就像

代码语言:javascript
运行
复制
gfoldl'
  :: (Data a)
  => (forall d. Data d => r -> d -> r)
  -> r
  -> a  
  -> r
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-18 12:00:46

其思想是,Haskell中的代数数据类型的值具有以下形式

代码语言:javascript
运行
复制
C x_1 x_2 ... x_n

其中C是构造函数,x_i是参数。什么

代码语言:javascript
运行
复制
gfoldl app con

是将这样的值转化为

代码语言:javascript
运行
复制
con C `app` x_1 `app` x_2 ... `app` x_n

从而将a转换为c a。假设C的类型是

代码语言:javascript
运行
复制
C :: T_1 -> T_2 -> ... -> T_n -> D

然后让我们看看中间表达式的类型:

代码语言:javascript
运行
复制
con C                                   :: c (T_1 -> T_2 -> ... -> T_n -> D)
con C `app` x_1                         :: c (T_2 -> ... -> T_n -> D)
con C `app` x_1 `app` x_2               :: c (... -> T_n -> D)
con C `app` x_1 `app` x_2 ... `app` x_n :: c D

c上的参数化允许所有这些中间类型都不同。如果我们使用像gfoldl'这样的简单折叠,那么所有这些中间类型都必须是相同的。

gfoldl的动机是单一的泛化,使您能够表达SYB函数gmapQgmapT (以及其他几个)。gmapQgmapT的类型如下:

代码语言:javascript
运行
复制
gmapQ :: Data a => (forall d. Data d => d -> u) -> a -> [u]
gmapT :: Data a => (forall b. Data b => b -> b) -> a -> a

虽然gmapQ将一个a折叠成一个统一的u列表,并且可以使用gfoldl'表示,但对于gmapT来说,这是不可能的。

但是,使用gfoldl,我们可以使用c = Identity来获得类似于gmapT的东西,而使用c = Const来获得类似gmapQ的东西。

要了解更多细节,您可能还需要查看论文把你的样板重装起来,它表明gfoldl是一种数据类型的普通(但更高的)折叠,该数据类型在该论文中称为Spine

使用恒等函子从单个基本表示中获得变换和更新行为与从"van Laarhoven“透镜获得透镜操作有一些相似之处。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29119986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档