前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Applicative 函子

Applicative 函子

作者头像
Sheepy
发布2018-09-10 12:25:14
7250
发布2018-09-10 12:25:14
举报
文章被收录于专栏:我杨某人的青春满是悔恨

Applicative 定律

Application 函子是一种加强的函子,在 Haskell 的 Control.Applicative 模块中定义了一个 Applicative 类型类:

代码语言:javascript
复制
class Functor f => Applicative (f :: * -> *) where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

同普通函子一样,一个类型构造器要成为 Applicative 的实例的话,它的 kind 必须是* -> *,即接受一个参数,返回一个具体类型。要成为 Applicative 类型类的实例,还必须定义两个函数,pure<*>。从这个定义来看,似乎只要是满足了以上几个条件的类型就可以称为 applicative 函子,事实上并非如此,要成为 applicative 函子还需要满足一条最重要的定律:

代码语言:javascript
复制
pure f <*> x = fmap f x

applicative 函子的用途很明确,就是为了取出第一个函子值中的函数,应用到第二个函子值的值上,上述定律基本可以保证<*>只是做了这件事,当然其他还有一些定律,就不细说了,列在这里大家看看就好:

代码语言:javascript
复制
pure id <*> v = v
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
pure f <*> pure x = pure (f x)
u <*> pure y = pure ($ y) <*> u

作为 applicative 的函数

我们知道函数可以作为函子,其实函数也可以作为 applicative:

代码语言:javascript
复制
instance Applicative ((->) r) where
  pure x = (\_ -> x)
  f <*> g = \x -> f x (g x)

这个可能稍微难理解一些,pure 取一个值,产生一个最小上下文,组合成一个 applicative 值,所以产生了一个忽略参数永远返回初始值(pure 的参数)的函数。至于<*>的话,先考虑函数作为普通函子的情况,我们知道函子值是一个包涵上下文的值,当函数作为函子值时,从这个上下文中取值的操作就是将一个参数传递给该函数,然后产生一个值,所以函数作为Functor类型类的实例时是这样的(这种情况下 fmap 其实就是函数组合.):

代码语言:javascript
复制
instance Functor ((->) r) where
  fmap f g = (\x -> f (g x))

我在函子定律中提到过,fmap 接收一个函数和一个函子值,取出函子值中的值传递给函数,然后返回一个函子值。当函数作为函子值时,fmap 还是返回一个函数(这里用 lambda 表示)。g 是函子值,我们要取出它的值,所以给它传递一个参数 x,然后将得到的值作为参数传递给 f,最后将得到的值包裹到 lambda 中(其实整个过程都是在 lambda 中,x 是 lambda 的参数)。那<*>也同理,它接收两个函子值,返回一个函子值,当函数作为函子值时,要先分别取出 f 中的值(函数)和 g 中的值,分别将一个参数 x 传递给它们,再将 g x 作为参数传递给 f x(由于 Haskell 自动柯里化的性质,f x 还是一个函数),最后将结果包裹到 lambda 中。

当然,将((->) r)作为 applicative 使用不是特别重要,但大家要理解并非只有容器或者某种数据结构才能作为函子。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.02.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Applicative 定律
  • 作为 applicative 的函数
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档