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. gitlab使用外部的postgresql、外部的redis服务器

    postgresql创建用户 su - postgres psql create role gitlab login encrypted password 'pass';\du ;显示用户 postg ...

  2. bzoj4247挂饰——压缩的动态规划

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4247 1.dp之前要先按挂钩个数从大到小排序,不然挂钩一度用成负的也可能是正确的,不仅脚标难 ...

  3. HttpCookieCollection类

    一.最近在研究HttpRequest类的时候,发现返回的cookie集合是存在放这个类的对象的.而实际上这个类只是一个HttpCookie对象的集合,关于HttpCookie类可以查看http://w ...

  4. Linux Home目录硬盘空间缩减

    Linux Home目录硬盘空间缩减 操作   基于centos6.5 x86_64, runlevel 3,命令行模式,测试成功. 1.首先查看磁盘使用情况 [root@localhost ~]# ...

  5. python中hashlib md5

    如下两种方法,结果相同 import hashlib import time m = hashlib.md5() m.update(str(time.time()).encode('utf-8')) ...

  6. 10个CSS+HOVER 的创意按钮

    CSS hover 样式很简单,但是想创造出有意思.实用.有创意性的特效是很考验设计师的创意能力,所以设计达人每隔一段时间都会分享一些与鼠标点击.悬停的相关特效,以便大家获得更好的创造灵感. 今天我们 ...

  7. TFS错误-TF249053

    前几天规划了下代码结构,改了很多东西后,台式机依然正常访问,但是笔记本一连接或者更改TFS相关资源就报错TF249053.报错点击后不影响正常使用,但是很郁闷.于是查了下资料如下. 错误原因: htt ...

  8. golang之配置环境

    从https://golang.org/dl/下载相关包,直接解压 目录大概这样 golang ├── go └── mods 配置环境变量 vim ~/.profile(debian需要勾选shel ...

  9. ubuntu 14.04 git clone 出现 fatal: Unable to find remote helper for 'https'

    当你编译安装git时因为没有安装(lib)curl-devel所以导致git clone 和 git push 都会出现这个错误 如果你安装了(lib)curl-devel,然后重新编译安装git就没 ...

  10. MySQL主从同步和半同步配置

    mysql主从配置: 1,安装maraidb,使用国内yum镜像站下载:[root@localhost mysql]# cat /etc/yum.repos.d/MairaDB.repo # Mari ...