Haskell语言学习笔记(26)Identity, IdentityT
Identity Monad
newtype Identity a = Identity { runIdentity :: a }
instance Functor Identity where
fmap = coerce
instance Applicative Identity where
pure = Identity
(<*>) = coerce
instance Monad Identity where
m >>= k = k (runIdentity m)
newtype Identity a = Identity { runIdentity :: a }
Identity 类型是个 newtype,也就是对现有类型的封装。该类型只有一个类型参数 a。
Identity a 封装了一个值:a,用 runIdentity 字段可以取出这个值。
Identity 是一个用于占位的 Monad。instance Monad Identity where
对比 Monad 类型类的定义,可知 return 函数的类型签名为:
return :: Identity a
而 bind 函数的类型签名为:
(>>=) :: a -> (a -> Identity b) -> Identity bm >>= k = k (runIdentity m)
证明 Identity 符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f ≡ Identity a >>= f ≡ f (runIdentity (Identity a)) ≡ f a
2. m >>= return ≡ m
m >>= return ≡ (Identity a) >> Identity ≡ Identity (runIdentity (Identity a)) ≡ Identity a ≡ m
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(m >>= f) >>= g
≡ ((Identity a) >>= f) >>= g
≡ f (runIdentity (Identity a)) >> = g
≡ f a >> g
m >>= (\x -> f x >>= g)
≡ (Identity a) >>= (\x -> f x >>= g)
≡ (\x -> f x >>= g) (runIdentity (Identity a))
≡ (\x -> f x >>= g) a
≡ f a >> g
IdentityT Monad转换器
newtype IdentityT f a = IdentityT { runIdentityT :: f a }
instance (Monad m) => Monad (IdentityT m) where
return = IdentityT . return
m >>= k = IdentityT $ runIdentityT . k =<< runIdentityT m
instance MonadTrans IdentityT where
lift = IdentityT
instance (MonadIO m) => MonadIO (IdentityT m) where
liftIO = IdentityT . liftIO
newtype IdentityT f a = IdentityT { runIdentityT :: f a }
IdentityT 类型是个 newtype,也就是对现有类型的封装。该类型有两个类型参数:内部 Monad 类型参数 f,以及值类型参数 a。
IdentityT f 类型封装了一个封装在内部 Monad f 中的值:f a,用 runIdentity 字段可以取出这个值。
Identity 是一个用于占位的 Monad转换器。instance (Monad m) => Monad (IdentityT m) where
如果 m 是个 Monad,那么 IdentityT m 也是一个 Monad。
对比 Monad 类型类的定义,可知 return 函数的类型签名为:
return :: IdentityT m a
而 bind 函数的类型签名为:
(>>=) :: a -> (a -> IdentityT m b) -> IdentityT m bm >>= k = IdentityT $ runIdentityT . k =<< runIdentityT m
证明 IdentityT 符合Monad法则:
1. return a >>= f ≡ f a
return a >>= f
≡ (IdentityT . return) a >>= f
≡ IdentityT (m a) >>= f
≡ IdentityT $ runIdentityT . f =<< runIdentityT (IdentityT (m a))
≡ IdentityT $ runIdentityT . f =<< m a
≡ IdentityT $ runIdentityT (f a)
≡ f a
2. m >>= return ≡ m
假设 m = IdentityT (n a)
m >>= return
≡ IdentityT $ runIdentityT . return =<< runIdentityT m
≡ IdentityT $ runIdentityT . (IdentityT . return) =<< runIdentityT (IdentityT (n a))
≡ IdentityT $ runIdentityT . (IdentityT . return) =<< n a
≡ IdentityT $ runIdentityT (IdentityT (n a))
≡ IdentityT (n a) ≡ m
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
(m >>= f) >>= g
≡ (IdentityT $ runIdentityT . f =<< runIdentityT m) >>= g
≡ IdentityT $ runIdentityT . g =<< runIdentityT (IdentityT $ runIdentityT . f =<< runIdentityT m)
≡ IdentityT $ runIdentityT . g =<< (runIdentityT . f =<< runIdentityT m)
≡ IdentityT $ (runIdentityT m >>= runIdentityT . f) >>= runIdentityT . g
m >>= (\x -> f x >>= g)
≡ IdentityT $ runIdentityT . (\x -> f x >>= g) =<< runIdentityT m
≡ IdentityT $ runIdentityT . (\x -> IdentityT $ runIdentityT . g =<< runIdentityT (f x)) =<< runIdentityT m
≡ IdentityT $ (\x -> runIdentityT $ IdentityT $ runIdentityT . g =<< runIdentityT (f x)) =<< runIdentityT m
≡ IdentityT $ (\x -> runIdentityT . g =<< runIdentityT (f x)) =<< runIdentityT m
≡ IdentityT $ runIdentityT m >>= (\x -> runIdentityT (f x) >>= runIdentityT . g)
根据内部 Monad 的法则:(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
IdentityT $ (runIdentityT m >>= runIdentityT . f) >>= runIdentityT . g
≡ IdentityT $ runIdentityT m >>= (\x -> (runIdentityT . f) x >>= runIdentityT . g)
≡ IdentityT $ runIdentityT m >>= (\x -> runIdentityT (f x) >>= runIdentityT . g)
证明 StateT 中 lift 函数的定义符合 lift 的法则。
1. lift . return ≡ return
lift . return $ a
≡ IdentityT (m a)
≡ return a
2. lift (m >>= f) ≡ lift m >>= (lift . f)
假设 m = n a 并且 f a = n b
于是 m >>= f = n b
lift (m >>= f)
≡ lift (n b)
≡ IdentityT (n b)
lift m >>= (lift . f)
≡ IdentityT (n a) >>= (\x -> lift . f $ x)
≡ IdentityT $ runIdentityT . IdentityT . f =<< runIdentityT (IdentityT (n a))
≡ IdentityT $ n a >>= f
≡ IdentityT (f a)
≡ IdentityT (n b)
Haskell语言学习笔记(26)Identity, IdentityT的更多相关文章
- 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语言学习笔记(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 ...
- Haskell语言学习笔记(30)MonadCont, Cont, ContT
MonadCont 类型类 class Monad m => MonadCont m where callCC :: ((a -> m b) -> m a) -> m a in ...
随机推荐
- Jmeter中Websocket协议支持包的使用(转)
转自:http://blog.csdn.net/typing_yes_no/article/details/49512167 参考的来源是国外一篇文章,已经整理成pdf格式(http://yunpan ...
- openwrt设置默认登陆密码
1.修改dropbear配置文件 找到package/network/services/dropbear/files/dropbear.config 修改如下: config dropbear opt ...
- MongoDB GUI( Robo 3T) Shell使用及操作
Robo 3T 下载及使用 之前叫 Robomongo,后面被收购了,改名 Robo 3T . 下载链接:https://robomongo.org/download (需要FQ) 安装步骤省略,下一 ...
- C#连接Oracle数据库的方法(Oracle.DataAccess.Client也叫ODP.net)
官方下载地址(ODP.net)(中文):http://www.oracle.com/technetwork/cn/topics/dotnet/downloads/index.html 官方下载地址(O ...
- Mysql 性能优化1 硬件设备的选择
--------------------------------------------目录------------------------------------------------- • 我们 ...
- Delphi控件备份工具
用途: 1.如果您需要重装Delphi,想省去重装控件的麻烦. 2.如果您把Delphi环境安装至另一台电脑上. 那么,您一定需要这个! 运行批处理后,自动在当前目录下生成备份目录. 批处理代码 @e ...
- JavaScript if(x),==和===解析(翻译整理)
一.if()中的布尔判断 if ( Expression ) 表达式会通过ES5定义的ToBoolean方法强制把Expression 转换成布尔值. 数据类型 转换结果 Undefined fals ...
- 中点Brehensam画圆算法
#include<stdio.h> #include<stdlib.h> #include<graphics.h> #include<math.h> v ...
- POJ 3268 Silver Cow Party 最短路径+矩阵转换
Silver Cow Party Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) T ...
- Bootstrap-CSS:网格系统
ylbtech-Bootstrap-CSS:网格系统 1.返回顶部 1. Bootstrap 网格系统 本章节我们将讲解 Bootstrap 的网格系统(Grid System). Bootstrap ...