Haskell语言练习
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语言练习的更多相关文章
- 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语言为什么值得你去学习
摘自http://www.vaikan.com/why-haskell-is-worth-learning/ Haskell语言为什么值得你去学习 当我向一些新手推荐学习Haskell语言时,得到的反 ...
- 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语言学习笔记(92)HXT
HXT The Haskell XML Toolbox (hxt) 是一个解析 XML 的库. $ cabal install hxt Installed hxt-9.3.1.16 Prelude&g ...
随机推荐
- Java队列Queue
上个星期总结了一下synchronized相关的知识,这次将Queue相关的知识总结一下,和朋友们分享. 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.Java提供 ...
- UE4 Sockets多线程TCP通信
转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...
- 在线学习和在线凸优化(online learning and online convex optimization)—FTL算法5
最自然的学习规则是使用任何在过去回合中损失最小的向量. 这与Consistent算法的精神相同,它在在线凸优化中通常被称为Follow-The-Leader,最小化累积损失. 对于任何t: 我们谈到了 ...
- spi and sensor
http://blog.csdn.net/DroidPhone/article/details/23367051 https://www.kernel.org/doc/html/v4.14/drive ...
- kafka的安装 (单机)
https://blog.csdn.net/q282176713/article/details/81112988
- 我推荐阅读的微信公众号-IT类
微信,正深刻影响着我们的生活,每个使用微信的人,从微信这个窗口去了解这个世界. 微信公众号,微信生态圈是核心功能之一,每天都有大量的文章创作.传播.转发出来,海量的信息扑面而来,微信阅读成为微信使用者 ...
- solr defType查询权重排序
Solr的defType有dismax/edismax两种,这两种的区别,可参见:http://blog.csdn.net/duck_genuine/article/details/8060026 下 ...
- MyBatis批量增删改查操作
前文我们介绍了MyBatis基本的增删该查操作,本文介绍批量的增删改查操作.前文地址:http://blog.csdn.net/mahoking/article/details/43673741 ...
- 在Java中多段执行adb或者shell的命令
public void Bale (String logname){ //ant打包 System.out.println("-----------正在执行ant编译-----------& ...
- Ruby学习笔记7: 添加身份验证(adding Authentication)
我们已经完成了Category & Product页面内容的增删改查,再加入一个身份验证即可成为一个较完整的Rails App了.本文就来完成这个任务. We now need to give ...