Monad

inc n = Just (n + 1)

add1 n = [n + 1]

main = do
print $ Nothing >> (Just 0) -- Nothing
print $ (Just 0) >> (Nothing :: Maybe Int) -- Nothing
print $ (Just 0) >> Nothing >> (Just 1) -- Nothing
print $ (Just 0) >> (Just 1) >> (Just 2) -- Just 2 print $ Nothing >>= inc >>= inc >>= inc -- Nothing
print $ (Just 0) >>= inc >>= inc >>= inc -- Just 3 print $ [] >> [1, 2] -- []
print $ [1, 2] >> ([] :: [Int]) -- []
print $ [1] >> [3, 4, 5] -- [3,4,5]
print $ [1, 2] >> [3, 4, 5] -- [3,4,5,3,4,5]
print $ [1, 2, 3] >> [3, 4, 5] -- [3,4,5,3,4,5,3,4,5] print $ [] >>= add1 >>= add1 >>= add1 -- []
print $ [1, 2, 3] >>= add1 -- [2,3,4]
print $ [1, 2, 3] >>= add1 >>= add1 -- [3,4,5]
print $ [1, 2, 3] >>= add1 >>= add1 >>= add1 -- [4,5,6]

根据 Monad Maybe 的定义、

instance  Monad Maybe  where
(Just x) >>= k = k x
Nothing >>= _ = Nothing Just _m1 >> m2 = m2
Nothing >> _m2 = Nothing

可得

Nothing >>= inc = Nothing
(Just 0) >>= inc
= (Just 0) >>= (\n -> Just (n + 1))
= (\n -> Just (n + 1)) 0
= Just (0 + 1) = Just 1 Nothing >> (Just 0) = Nothing
(Just 0) >> (Nothing :: Maybe Int) = Nothing
(Just 1) >> (Just 2) = Just 2

根据 Monad [] 的定义、

instance Monad []  where
xs >>= f = [y | x <- xs, y <- f x]
xs >> ys = [y | _ <- xs, y <- ys]

可得

[1, 2, 3] >>= add1
= [1, 2, 3] >>= (\n -> [n + 1])
= [y | x <- [1, 2, 3], y <- [x + 1]]
= [2,3,4]
[1, 2, 3] >> [3, 4, 5]
= [y | _ <- [1, 2, 3], y <- [3, 4, 5]]
= [3,4,5,3,4,5,3,4,5]

State Monad

import Control.Monad.State

inc :: State Int Int
inc = do
n <- get
put (n + 1)
return n incBy :: Int -> State Int Int
incBy x = do
n <- get
modify (+x)
return n main = do
print $ evalState inc 1 -- 1
print $ execState inc 1 -- 2
print $ runState inc 1 -- (1,2)
print $ runState (withState (+3) inc) 1 -- (4,5)
print $ runState (mapState (\(a, s) -> (a + 3, s + 4)) inc) 1 -- (4,6) print $ runState (incBy 5) 10 -- (10,15)

关于 State Monad

get 将结果值设置为状态值 s,状态值 s 保持不变。

put s 将结果值设为空,将状态值设为 s。

return a 将结果值设为 a,状态值 s 保持不变。

modify f 将结果值设为空,将状态值设为 f s。

gets f 将结果值设为 f s,状态值 s 保持不变。

由此可得

--  假设初始状态值为 s
inc = do
n <- get -- (s,s)
put (n + 1) -- ((),s + 1)
return n -- (s,s + 1)
-- 假设初始状态值为 s
incBy x = do
n <- get -- (s,s)
modify (+x) -- ((),s + x)
return n -- (s,s + x)

关于 State Monad

evalState s 针对 State Monad 利用初始状态值 s 进行状态计算,然后返回最终结果值 a’。

execState s 针对 State Monad 利用初始状态值 s 进行状态计算,然后返回最终状态值 s’。

runState s 针对 State Monad 利用初始状态值 s 进行状态计算,然后返回最终结果值和最终状态值组成的一对值 (a’, s')。

mapState f 针对 State Monad 进行状态计算之后,对最终结果值和状态值调用函数 f。

withState f 针对 State Monad 进行状态计算之前,对初始状态值调用函数 f。

由此可得

runState inc 1 = (1,1 + 1) = (1,2)
evalState inc 1 = 1
execState inc 1 = 2
runState (incBy 5) 10 = (10,10 + 5) = (10,15)
runState (withState (+3) inc) 1
= runState inc ((+3) 1)
= runState inc 4
= (4,5)
runState (mapState (\(a, s) -> (a + 3, s + 4)) inc) 1
= (\(a, s) -> (a + 3, s + 4)) (runState inc 1)
= (\(a, s) -> (a + 3, s + 4)) (1,2)
= (4,6)

Reader Monad

import Control.Monad.Reader

data Environment = Environment { text1 :: String, text2 :: String }

getText :: Reader Environment String
getText = do
t1 <- asks text1 -- Hello
t2 <- asks text2 -- world!
t3 <- withReader text1 ask -- Hello
t4 <- mapReader text2 ask -- world!
return $ t1 ++ ", " ++ t2 ++ ", " ++ t3 ++ ", " ++ t4 main = print $ runReader getText $ Environment "Hello" "world!"

Writer Monad

import Control.Monad.Writer

write :: Int -> Writer [Int] String
write n = do
tell [1..n]
return "Done" main = do
print $ runWriter $ write 10 -- ("Done",[1,2,3,4,5,6,7,8,9,10])
print $ execWriter $ write 10 -- [1,2,3,4,5,6,7,8,9,10]

Haskell语言练习的更多相关文章

  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语言为什么值得你去学习

    摘自http://www.vaikan.com/why-haskell-is-worth-learning/ Haskell语言为什么值得你去学习 当我向一些新手推荐学习Haskell语言时,得到的反 ...

  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语言学习笔记(44)Lens(2)

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

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

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

  10. Haskell语言学习笔记(92)HXT

    HXT The Haskell XML Toolbox (hxt) 是一个解析 XML 的库. $ cabal install hxt Installed hxt-9.3.1.16 Prelude&g ...

随机推荐

  1. 通过注解实现一个简易的Spring mvc框架

    1.首先我们来搭建架构,就建一个普通的javaweb项目就OK了,具体目录如下: 对于小白来说可以细看后面web.xml的配置,对javaweb有点研究可以忽略而过后面的web.xml配置. 2.先上 ...

  2. Spring之Ioc原理

    ioc 控制反转 使用的 单例模式 和 工厂模式 单例模式保证创建对象的唯一性 工厂模式实现解耦合的作用 通过dm4j类似的技术读取xml文件中bean标签的属性值,id和class 利用反射技术和c ...

  3. MFC+mongodb+nodejs 数据库的读取与写入操作

    首先通过nodejs和mongodb建立后端服务器 一.在windows平台下启动mongodb服务器 1.进入mongodb的安装目录,并进去bin目录启动mongod 2.在d盘建立mongodb ...

  4. 【Unix网络编程】chapter8基本UDP套接字编程

    chapter8基本UDP套接字编程 8.1 概述 典型的UDP客户端/服务端的函数调用 8.2 recvfrom和sendto函数 #include <sys/socket.h> ssi ...

  5. 电商系统架构总结1(EF)

    最近主导了一个电商系统的设计开发过程,包括前期分析设计,框架搭建,功能模块的具体开发(主要负责在线支付部分),成功上线后的部署维护,运维策略等等全过程. 虽然这个系统不是什么超大型的电商系统 数亿计的 ...

  6. Java 2-Java 对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为. ...

  7. python连接RabbitMQ

    安装PIP wget "https://pypi.python.org/packages/source/p/pip/pip-1.5.4.tar.gz tar -xzvf pip-.tar.g ...

  8. hdfs底层存储分隔符

    字段分割 \ map字段里面key \ value \ 每行结尾用linux换行符 \0a '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标下移一格,通常敲一个回车键,即是回车,又是换行( ...

  9. chattr和lsattr命令的使用(对于root用户也无法修改删除的操作问题)

    1.chattr命令的用法:chattr [+-=] [ASacdistu] File/Directory 参数说明: +-= :分别为 [+ 增加] [- 减少] [= 设定] 属性的意思 A :当 ...

  10. 0. 资料官网【从零开始学Spring Boot】

    [视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...