Haskell语言学习笔记(42)Bifunctor
Bifunctor
class Bifunctor p where
bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
bimap f g = first f . second g
first :: (a -> b) -> p a c -> p b c
first f = bimap f id
second :: (b -> c) -> p a b -> p a c
second = bimap id
Bifunctor(双协变函子) 是个类型类。
Bifunctor类型类带两个协变类型参数。
Bifunctor类型类包含三个函数。
- bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
bimap函数同时修改 Bifunctor 的两个参数。 - first :: (a -> b) -> p a c -> p b c
first函数只修改 Bifunctor 的第一个参数。 - second :: (b -> c) -> p a b -> p a c
second函数只修改 Bifunctor 的第二个参数。
Bifunctor 的法则
法则
bimap id id ≡ id
first id ≡ id
second id ≡ id
bimap f g ≡ first f . second g
推论
bimap (f . g) (h . i) ≡ bimap f h . bimap g i
first (f . g) ≡ first f . first g
second (f . g) ≡ second f . second g
Either 是个Bifunctor
instance Bifunctor Either where
bimap f _ (Left a) = Left (f a)
bimap _ g (Right b) = Right (g b)
(,) 是个Bifunctor
instance Bifunctor (,) where
bimap f g ~(a, b) = (f a, g b)
Const 是个Bifunctor
instance Bifunctor Const where
bimap f _ (Const a) = Const (f a)
应用 Bifunctor
Prelude Data.Bifunctor> bimap (+2) (*3) (1,2)
(3,6)
Prelude Data.Bifunctor> bimap (+2) (*3) (Left 2)
Left 4
Prelude Data.Bifunctor> bimap (+2) (*3) (Right 2)
Right 6
Prelude Data.Bifunctor> first (+2) (1,2)
(3,2)
Prelude Data.Bifunctor> second (*3) (1,2)
(1,6)
Prelude Data.Bifunctor> first (+2) (Left 2)
Left 4
Prelude Data.Bifunctor> second (*3) (Right 2)
Right 6
Prelude Data.Bifunctor Control.Applicative> first (+2) (Const 2)
Const 4
Prelude Data.Bifunctor Control.Applicative> second (+2) (Const 2)
Const 2
Haskell语言学习笔记(42)Bifunctor的更多相关文章
- Haskell语言学习笔记(88)语言扩展(1)
ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- Haskell语言学习笔记(69)Yesod
Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...
- Haskell语言学习笔记(20)IORef, STRef
IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...
- Haskell语言学习笔记(39)Category
Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...
- Haskell语言学习笔记(84)Concurrent
Control.Concurrent Prelude> import Control.Concurrent Prelude Control.Concurrent> Control.Conc ...
- Haskell语言学习笔记(72)Free Monad
安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...
- Haskell语言学习笔记(49)ByteString Text
Data.ByteString String 是 [Char] 的同义词,在使用上存在List的惰性所带来的性能问题. 在处理大型二进制文件时,可以使用 ByteString 来代替 String. ...
- Haskell语言学习笔记(44)Lens(2)
自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...
随机推荐
- HTML5 localStorage使用教程
在客户端存储数据,HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前, ...
- Grid中添加链接,打开选项卡页面
如何在grid中点击,添加一个选项卡并打开页面 function addeditnew(id, title) { var node ...
- 核心重点lxml
from lxml import html htmlStr = html.etree.HTML(pagehtml, parser= html.etree.HTMLParser(encoding='ut ...
- eclipse 新项目导入到tfs 步骤
为了下次导入项目 不动脑子,写下此步骤.... 1.右键要导入的项目>> share project(如果有这项就点它,然后 进入 分享至你的tfs服务器即可) 1.右键要导入的项目> ...
- springMVC集成CXF快速发布webService
本文转载自:http://www.cnblogs.com/xiaochangwei/p/5399507.html 继上一篇webService入门之后,http://www.cnblogs.com/x ...
- 反射中Class.forName()和ClassLoader.loadClass()的区别
一 Java类装载过程 装载:通过累的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象: 链接:执行下面的校验.准备和解析步骤,其 ...
- (转)USB中CDC-ECM的了解和配置
USB中典型类及子类: 类别 解释 子类 典型应用 IC芯片 备注 UVC 视频类 免驱USB摄像头 CDC 通讯类 RNDIS ECM(p24) 免驱USB网卡 RTL8152B EEM ..... ...
- Oracle跨库复制表结构
1.首先建立远程连接 create public database link LINK_SJPSconnect to system identified by manager using '(DESC ...
- 自己根据js的兼容封装了一个小小的js库
var gys = function () { } //oParent父节点 //获取所有的子元素 gys.prototype.getElementChildren = function (oPare ...
- OPatch failed with error code 73(OracleHomeInventory gets null oracleHomeInfo)
OPatch failed with error code 73(OracleHomeInventory gets null oracleHomeInfo) 1.问题描述 [oracle@dou_ra ...