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 ...
随机推荐
- js 各种循环遍历
js 各种循环遍历(表格比较) 遍历方法 能否遍历数组 能否遍历对象 备注 for 能 不能 for in 能(有诸多缺点) 能 为遍历对象而设计的,不适用于遍历数组 forEach 能 不能 bre ...
- Mysql 性能优化2 系统参数配置方法 和 文件系统
--------------------------------------------目录------------------------------------------------- • 关于 ...
- java Map实例
此段资料在自于<黑马程序员_毕向东_Java基础视频教程第16天-06-集合(Map练习)> HashMap 如果对象可能会产生很多对象,可能就会需要存储,就有可能会存到hashSet(哈 ...
- Spring和Quartz集成
本文转载自:http://blog.csdn.net/u010648555/article/details/54891264 Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企 ...
- bzoj2026: [SHOI2009]Coin
Description Constantine刚结束在MySky Island的度假,正准备离开的时候,他想送给她的好朋友YY一份特别的礼物——MySky Island上特别的手工艺品宝石纪念币.宝石 ...
- 解决nginx启动时域名解析失败而导致服务启动失败的问题
问题: nginx启动或者reload的时候,会对proxy_pass后面的域名进行DNS解析,如果解析失败,启动就会失败或者reload失败. 我们是to B的产品,客户的环境可能是不通公网的,因此 ...
- ThinkJava-多态
8.2.1 方法调用绑定 解决的办法就是后期绑定,它的含义就是在运行时根据对象的类型进行绑定.后期绑定也 叫做动态绑定或运行时绑定.如果一种语言想实现后期绑定,就必须具有某种机制,以便在运 行时能判断 ...
- php7 数据库操作的 方法
连接数据库的方法PHP7.0以上的: 方法一: <?php/* Connect to a MySQL server 连接数据库服务器 */$link = mysqli_connect('loca ...
- python动态函数hasattr,getattr,setattr,delattr
hasattr(object,name) hasattr用来判断对象中是否有name属性或者name方法,如果有,染回true,否则返回false class attr(): def fun( ...
- 9.简单理解ajax
#### post 请求需要发送一个header setRequestHeader('Content-Type','application/x-www-form-urlencoded') post请求 ...