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的更多相关文章

  1. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  2. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  3. Haskell语言学习笔记(69)Yesod

    Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...

  4. Haskell语言学习笔记(20)IORef, STRef

    IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...

  5. Haskell语言学习笔记(39)Category

    Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...

  6. Haskell语言学习笔记(84)Concurrent

    Control.Concurrent Prelude> import Control.Concurrent Prelude Control.Concurrent> Control.Conc ...

  7. Haskell语言学习笔记(72)Free Monad

    安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...

  8. Haskell语言学习笔记(49)ByteString Text

    Data.ByteString String 是 [Char] 的同义词,在使用上存在List的惰性所带来的性能问题. 在处理大型二进制文件时,可以使用 ByteString 来代替 String. ...

  9. Haskell语言学习笔记(44)Lens(2)

    自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...

随机推荐

  1. php实现cookie加密解密

    1.加密解密类 class Mcrypt { /** * 解密 * * @param string $encryptedText 已加密字符串 * @param string $key 密钥 * @r ...

  2. ORACLE基本操作备忘

    通过CMD登录SQLPLUS 的语句 C:\Users\Administrator>sqlplus /nolog SQL> conn sys/pwd as sysdba; 导入导出数据库( ...

  3. Joyoi公路乘车(原tyvj1015)

    题目:http://www.joyoi.cn/problem/tyvj-1015 水题.连优化都不用. #include<iostream> #include<cstdio> ...

  4. 【appium】keyevent的keycode

    方法1 AppiumDriver实现了在上述功能,代码如下(java版本) driver.sendKeyEvent(66); 方法2 HashMap<String, Integer> ke ...

  5. HttpClient连接池

    HttpClient连接池,发现对于高并发的请求,效率提升很大.虽然知道是因为建立了长连接,导致请求效率提升,但是对于内部的原理还是不太清楚.后来在网上看到了HTTP协议的发展史,里面提到了一个属性C ...

  6. android自定义控件的一个思路-入门

    转自:http://blog.sina.com.cn/s/blog_691051e10101a3by.html   很多时候没有我们需要使用的控件,或者控件并不美观.比如这个滑动开关,这是androi ...

  7. 【Active入门-2】ActiveMQ学习-生产者与消费者

    1个生产者,1个消费者,使用Queue: 方式1: 生产者将消息发送到Queue中,退出: 然后运行消费者: . 可以看到,可以接收到消息. 方式2: 先运行消费者程序: 然后运行生产者: 消费者见下 ...

  8. JavaScript if(x),==和===解析(翻译整理)

    一.if()中的布尔判断 if ( Expression ) 表达式会通过ES5定义的ToBoolean方法强制把Expression 转换成布尔值. 数据类型 转换结果 Undefined fals ...

  9. 转转转!SpringMVC访问静态资源的三种方式

    如果你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...

  10. Air test ios类使用

    1.iOS手机的滑动 相关代码 #python class IOS(Device): ... @property #获取屏幕的尺寸 def display_info(self): if not sel ...