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 b

  • m >>= 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 b

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

  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语言学习笔记(72)Free Monad

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

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

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

  8. Haskell语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...

  9. Haskell语言学习笔记(30)MonadCont, Cont, ContT

    MonadCont 类型类 class Monad m => MonadCont m where callCC :: ((a -> m b) -> m a) -> m a in ...

随机推荐

  1. linux yum安装httpd后,启动service httpd start 报错解决方案

    解决方案:

  2. POJ2127 LICS模板

    题目:http://poj.org/problem?id=2127 十分费劲地终于记录好了路径……用一个前驱. 这是 n^2 的LICS方法.其实就是 n ^ 2 log n 把“找之前的d [ j ...

  3. openwrt设置默认登陆密码

    1.修改dropbear配置文件 找到package/network/services/dropbear/files/dropbear.config 修改如下: config dropbear opt ...

  4. spring boot学习(4) SpringBoot 之Spring Data Jpa 支持(1)

    第一节:Spring Data Jpa 简介 Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate ...

  5. ASP.NET Web Pages:目录

    ylbtech-.Net-ASP.NET Web Pages:目录 1. 官网返回顶部 1. https://www.asp.net/web-pages 2. https://msdn.microso ...

  6. [转]CSKIN 作者分享的图片处理类

    本代码来自:http://bbs.cskin.net/forum.php?mod=viewthread&tid=113&fromuid=2446 里面没有我想找的任意角度旋转的方法,代 ...

  7. xgCalendar在ASP.NET中的使用

    1.将wdCalendar文件夹考入项目中 2.在页面中添加引用,见3中head标签中定义 3.配置xgCalendar,两段代码放在一起就是完整的页面 body> <div> &l ...

  8. VS2013下.Net Framework4配置FineUI4.14

    配置步骤: 工具箱:空白处右键--选项卡--浏览,选择FineUI.dll配置web.config,管道模式设置为:传统 配置web.config 在form表单下添加: <f:PageMana ...

  9. Linux--多网卡的7种Bond模式和交换机配置

    网卡bond是通过把多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡.在应用部署中是一种常用的技术,我们公司基本所有的项目相关服务器都做了bond,这里总结整理,以便待查. bond ...

  10. Determining IP information for eth0...failed 错误解决

    问题描述:虚拟机使用wget命令上网,执行service network restart后出现如下错误Determining IP information for eth0...failed解决办法: ...