Haskell语言学习笔记(45)Profunctor
Profunctor
class Profunctor p where
dimap :: (a -> b) -> (c -> d) -> p b c -> p a d
dimap f g = lmap f . rmap g
lmap :: (a -> b) -> p b c -> p a c
lmap f = dimap f id
rmap :: (b -> c) -> p a b -> p a c
rmap = dimap id
Profunctor(逆变协变函子) 是个类型类。
Profunctor类型类带两个类型参数,第一个逆变,第二个协变。
Profunctor类型类包含三个函数。
- dimap :: (a -> b) -> (c -> d) -> p b c -> p a d
dimap函数同时修改 Profunctor 的两个参数。 - lmap :: (a -> b) -> p b c -> p a c
lmap函数只修改 Profunctor 的第一个参数。 - rmap :: (b -> c) -> p a b -> p a c
rmap函数只修改 Profunctor 的第二个参数。
Profunctor类型类实际上将输入输出的概念一般化。
Profunctor p b c 对于输入 b 是逆变,对于输出 c 则是协变。
Profunctor 的法则
法则
dimap id id ≡ id
lmap id ≡ id
rmap id ≡ id
dimap f g ≡ lmap f . rmap g
推论
dimap (f . g) (h . i) ≡ dimap g h . dimap f i
lmap (f . g) ≡ lmap g . lmap f
rmap (f . g) ≡ rmap f . rmap g
(->) 是个Profunctor
instance Profunctor (->) where
dimap ab cd bc = cd . bc . ab
lmap = flip (.)
rmap = (.)
Prelude Data.Profunctor> lmap (+2) (*3) $ 4
18
Prelude Data.Profunctor> rmap (+3) (*3) $ 4
15
Prelude Data.Profunctor> dimap (+2) (+3) (*3) $ 4
21
- (->) 是个典型的Profunctor,它具有输入和输出。
- lmap (+2) (*3) $ 4 = (4+2)*3 = 18
- rmap (+3) (*3) $ 4 = 4*3+3 = 15
- dimap (+2) (+3) (*3) $ 4 = (4+2)*3+3 = 21
- dimap (+2) (+3) (*3) = (+3) . (*3) . (+2)
Star 是个 Profunctor
newtype Star f d c = Star { runStar :: d -> f c }
instance Functor f => Profunctor (Star f) where
dimap ab cd (Star bfc) = Star (fmap cd . bfc . ab)
lmap k (Star f) = Star (f . k)
rmap k (Star f) = Star (fmap k . f)
Star 类型将 Functor 正向提升为 Profunctor
- newtype Star f d c = Star { runStar :: d -> f c }
Star 封装了一个输出为 Functor 的函数: d -> f c。 - dimap ab cd (Star bfc) = Star (fmap cd . bfc . ab)
dimap 函数将第一个函数 ab 应用到函数的输入端,将第二个函数 cd 应用到函数的输出端(通过fmap)。
Prelude Data.Profunctor> runStar (dimap (+1) show (Star Just)) 5
Just "6"
Prelude Data.Profunctor> runStar (dimap (+1) show (Star (\x -> [x, x+1]))) 5
["6","7"]
runStar (dimap (+1) show (Star Just)) 5 = fmap show . Just . (+1) $ 5
Costar 是个 Profunctor
newtype Costar f d c = Costar { runCostar :: f d -> c }
instance Functor f => Profunctor (Costar f) where
dimap ab cd (Costar fbc) = Costar (cd . fbc . fmap ab)
lmap k (Costar f) = Costar (f . fmap k)
rmap k (Costar f) = Costar (k . f)
Costar 类型将 Functor 反向提升为 Profunctor。
- newtype Costar f d c = Costar { runCostar :: f d -> c }
Costar 封装了一个输入为 Functor 的函数: f d -> c。 - dimap ab cd (Costar fbc) = Costar (cd . fbc . fmap ab)
dimap 函数将第一个函数 ab 应用到函数的输入端(通过fmap),将第二个函数 cd 应用到函数的输出端。
Prelude Data.Profunctor> runCostar (dimap (+1) show (Costar sum)) [1,2,3]
"9"
Prelude Data.Profunctor> runCostar (dimap (+1) show (Costar Data.Maybe.fromJust)) (Just 3)
"4"
runCostar (dimap (+1) show (Costar sum)) [1,2,3] = show . sum . fmap (+1) $ [1,2,3]
Forget 是个 Profunctor
newtype Forget r a b = Forget { runForget :: a -> r }
instance Profunctor (Forget r) where
dimap f _ (Forget k) = Forget (k . f)
lmap f (Forget k) = Forget (k . f)
rmap _ (Forget k) = Forget k
Haskell语言学习笔记(45)Profunctor的更多相关文章
- 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语言学习笔记(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 ...
- Haskell语言学习笔记(38)Lens(1)
Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...
随机推荐
- POJ2584 T-Shirt Gumbo——网络最大流模板
题目:http://poj.org/problem?id=2584 像模板一样的简单题.继续使用 & 的当前弧优化和神奇的构造函数. #include<iostream> #inc ...
- 消息中间件 ActiveMQ的简单使用
一.AactiveMQ的下载和安装 1. 下载ActiveMQ 地址:http://activemq.apache.org/activemq-5152-release.html 我这里下载的是wind ...
- python 异常类型----后期需理解调整
1.Python内建异常体系结构The class hierarchy for built-in exceptions is: BaseException +-- SystemExit +-- Key ...
- java学习之路之javaSE基础2
java学习之路之javaSE基础2 所有的代码都是引用他人写的. 1.逻辑运算符 //&,|,^,! //int x = 10; //5 < x < 15 //x > 5 ...
- php生成随机颜色代码
function rand_color($color_array) { $color = dechex(rand(3355443,13421772)); if (in_array($color, $c ...
- 读取Apache访问日志,查看每一个独立客户端连接获得的字节数
ubuntu中apache2的日志文件位于: /var/log/apache2 代码: # coding=utf-8 import sys ''' 数据 127.0.0.1 - - [10/Jan/2 ...
- shell 7echo命令
echo用于字符串的输出 1. 显示普通字符串 #shell #!/bin/sh echo "Hello world" echo Hello world Hello world H ...
- pycharm fiddler requests.exceptions.SSLError
一.SSL问题1.不启用fiddler,直接发https请求,不会有SSL问题(也就是说不想看到SSL问题,关掉fiddler就行) 2.启动fiddler抓包,会出现这个错误:requests.ex ...
- 关于win时间同步的解决方案
将以下的批处理执行:net stop w32time sc config w32time start= auto net start w32time w32tm /config /update /ma ...
- VMware仅主机模式访问外网
原文转载至:https://blog.csdn.net/eussi/article/details/79054622 保证VMware Network Adapter VMnet1是启用状态 将可以 ...