热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

haskell的世界观(2)

一个Monadm定义了一个运算(computation):图中上面一个是monadma,下面一个是function(a->mb)。

一个Monad m定义了一个运算(computation):
图中上面一个是monad m a,下面一个是function (a->mb)。
可以大致这么理解,一个monad是包含两面的,它除了在一个世界中作为a以外,还携带了另外一个世界如何从in变化到out的信息。所以,一个monad还叫做action,或者computation。例如,IO monad又称IO action。后面为了不用每次画图,我们这样画一个monad:
a//in->out,或者a//in,或者a//out
而a->m b这样画:
a->b//in->out
 
 
Monad有四个基本运算分别是:bind(>>=), then(>>), return, fail。
 
 
从数学的角度讲,一个monad只需要两个运算,>>=和return就够了。不过从程序设计角度,为了便利,添加了>>和fail,他们分别是>>=和return的特化型。
 
bind运算把一个monad m a的pure部分取出来,放到一个monad constructor (a->m b)中,构造器产生一个新的monad m b,借此把a输送给real world。
then运算是特殊的bind,它描述了两个monad的顺序诞生。
return运算是一个特殊的constructor,它接受一个pure world中的a,产生一个monad m a。
fail运算是特殊的return,它接受一个String之后,产生一个monad,同时把这个String输送给real world。
 
monad三定律:
(1) return a >>= k  ==  k a
(2) m >>= return  ==  m
(3) m >>= (/x -> k x >>= h)  ==  (m >>= k) >>= h
 
第一个,monad bind到constructor等价于直接apply monad中的pure部分到constructor。
第二个,return保留monad的所有信息不变。
第三个,bind运算满足结合律。
 
好了,看了这么些难以理解的概念之后,让我们看看几个实际的例子吧。
 
1. putStrLn :: String -> IO ()
putStrLn函数根据pure world中的一个String构造了一个IO monad IO ()。
 
2. Just :: a -> Maybe a
Just这个constructor根据a构造一个Maybe monad Maybe a。
试试把一个Maybe monad bind到print看看:
Prelude> (Just 3)>>=print
    Couldn't match expected type `Maybe' against inferred type `IO'
      Expected type: t -> Maybe b
      Inferred type: t -> IO ()
看起来,monad只能bind到能够构造同类型monad的constructor上。
Prelude> let f x | x>=0 = Just (x+1) | x<0 = Nothing
Prelude> :t f
f :: (Ord a, Num a) => a -> Maybe a
Prelude> (Just 3)>>=f
Just 4
Prelude> (Just (-1))>>=f
Nothing
进一步看看:
Prelude> :t f 3
f 3 :: (Ord t, Num t) => Maybe t
Prelude> :t f (-1)
f (-1) :: (Ord a, Num a) => Maybe a
可以看到,real world中不是只有I/O一种action。
 
3. rollDice = getStdRandom (randomR (1,6)) :: IO Integer
这是一个随机数产生函数。
试试看:
Prelude> :m System.Random
Prelude System.Random> let rollDice = getStdRandom(randomR(1,6))
Prelude System.Random> mapM (/x->rollDice) [1..12]
[3,5,3,6,2,4,5,1,5,6,3,2]
 
 
st.monad@gmail.com原创,转贴请注明出处,谢谢!
 

推荐阅读
author-avatar
等着日落看日出222
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有