小智..

5

tl; dr

{-# LANGUAGE InstanceSigs #-}

newtype Id t = Id t

instance Monad Id where

return :: t -> Id t

return = Id

(=< Id b) -> Id a -> Id b

f =<< (Id x) = f x

序幕

$函数的应用运算符

forall a b. a -> b

规范定义

($) :: (a -> b) -> a -> b

f $ x = f x

infixr 0 $

就Haskell原始函数应用f x(infixl 10)而言。

组成.定义$为

(.) :: (b -> c) -> (a -> b) -> (a -> c)

f . g = \ x -> f $ g x

infixr 9 .

并满足等效条件 forall f g h.

f . id = f :: c -> d Right identity

id . g = g :: b -> c Left identity

(f . g) . h = f . (g . h) :: a -> d Associativity

.是关联的,id是左右身份。

克莱斯里三人组

在编程中,monad是函子类型构造函数,具有monad类型类的实例。定义和实现有几种等效的变体,每种变体对monad抽象的理解都略有不同。

一个仿函数是一种构造f一种* -> *与仿函数类型的类的实例。

{-# LANGUAGE KindSignatures #-}

class Functor (f :: * -> *) where

map :: (a -> b) -> (f a -> f b)

除遵循静态强制类型协议外,函子类型类的实例还必须遵守代数函子定律 forall f g.

map id = id :: f t -> f t Identity

map f . map g = map (f . g) :: f a -> f c Composition / short cut fusion

函子计算具有以下类型

forall f t. Functor f => f t

一个计算c r包括在结果 r中的上下文 c。

一元单子函数或Kleisli箭头具有以下类型

forall m a b. Functor m => a -> m b

Kleisi箭头是具有一个参数a并返回一元计算的函数m b。

Monads是按照Kleisli三元规范定义的 forall m. Functor m =>

(m, return, (=<

实现为类型类

class Functor m => Monad m where

return :: t -> m t

(=< m b) -> m a -> m b

infixr 1 =<<

所述Kleisli身份 return是Kleisli箭头促进的值t成一元上下文m。Extension或Kleisli应用程序 =< m b计算结果m a。

Kleisli组成 <=

(<= (b -> m c) -> (a -> m b) -> (a -> m c)

f <=< g = \ x -> f =<< g x

infixr 1 <=<

<=< 组成两个Kleisli箭头,将左箭头应用于右箭头应用的结果。

monad类型类的实例必须遵守monad法则,就Kleisli组成而言,其用法最为优美:forall f g h.

f <=< return = f :: c -> m d Right identity

return <=< g = g :: b -> m c Left identity

(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d Associativity

<=

身分识别

身份类型

type Id t = t

是类型上的标识函数

Id :: * -> *

解释为函子,

return :: t -> Id t

= id :: t -> t

(=< Id b) -> Id a -> Id b

= ($) :: (a -> b) -> a -> b

(<= Id c) -> (a -> Id b) -> (a -> Id c)

= (.) :: (b -> c) -> (a -> b) -> (a -> c)

在规范的Haskell中,标识monad被定义

newtype Id t = Id t

instance Functor Id where

map :: (a -> b) -> Id a -> Id b

map f (Id x) = Id (f x)

instance Monad Id where

return :: t -> Id t

return = Id

(=< Id b) -> Id a -> Id b

f =<< (Id x) = f x

选项

选项类型

data Maybe t = Nothing | Just t

Maybe t对不一定会产生结果的t计算进行编码,即可能“失败”的计算。选项monad已定义

instance Functor Maybe where

map :: (a -> b) -> (Maybe a -> Maybe b)

map f (Just x) = Just (f x)

map _ Nothing = Nothing

instance Monad Maybe where

return :: t -> Maybe t

return = Just

(=< Maybe b) -> Maybe a -> Maybe b

f =<< (Just x) = f x

_ =<< Nothing = Nothing

a -> Maybe b仅当Maybe a产生结果时才应用于结果。

newtype Nat = Nat Int

可以将自然数编码为大于或等于零的那些整数。

toNat :: Int -> Maybe Nat

toNat i | i >= 0 = Just (Nat i)

| otherwise = Nothing

减法不会关闭自然数。

(-?) :: Nat -> Nat -> Maybe Nat

(Nat n) -? (Nat m) = toNat (n - m)

infixl 6 -?

选项monad涵盖了异常处理的基本形式。

(-? 20) <=< toNat :: Int -> Maybe Nat

清单

列表单子,在列表类型之上

data [] t = [] | t : [t]

infixr 5 :

并且其附加的monoid操作“附加”

(++) :: [t] -> [t] -> [t]

(x : xs) ++ ys = x : xs ++ ys

[] ++ ys = ys

infixr 5 ++

对非线性计算进行编码[t]产生自然0, 1, ...的结果t。

instance Functor [] where

map :: (a -> b) -> ([a] -> [b])

map f (x : xs) = f x : map f xs

map _ [] = []

instance Monad [] where

return :: t -> [t]

return = (: [])

(=< [b]) -> [a] -> [b]

f =<< (x : xs) = f x ++ (f =<< xs)

_ =<< [] = []

扩展将将Kleisli箭头应用于的元素所得到的所有列表=< [b][a][b]

让一个正整数的正确除数n是

divisors :: Integral t => t -> [t]

divisors n = filter (`divides` n) [2 .. n - 1]

divides :: Integral t => t -> t -> Bool

(`divides` n) = (== 0) . (n `rem`)

然后

forall n. let { f = f <=< divisors } in f n = []

在定义monad类型类而不是扩展时=<>=。

class Applicative m => Monad m where

(>>=) :: forall a b. m a -> (a -> m b) -> m b

(>>) :: forall a b. m a -> m b -> m b

m >> k = m >>= \ _ -> k

{-# INLINE (>>) #-}

return :: a -> m a

return = pure

为简单起见,此说明使用类型类层次结构

class Functor f

class Functor m => Monad m

在Haskell中,当前的标准层次结构为

class Functor f

class Functor p => Applicative p

class Applicative m => Monad m

因为不仅每个monad都是函子,而且每个应用程序都是函子,每个monad也都是应用程序。

使用列表monad,命令伪代码

for a in (1, ..., 10)

for b in (1, ..., 10)

p

if even(p)

yield p

大致翻译为do块,

do a

b

let p = a * b

guard (even p)

return p

等效的monad理解,

[ p | a

和表达

[1 .. 10] >>= (\ a ->

[1 .. 10] >>= (\ b ->

let p = a * b in

guard (even p) >> -- [ () | even p ] >>

return p

)

)

注解和monad理解是嵌套绑定表达式的语法糖。bind操作符用于单子结果的本地名称绑定。

let x = v in e = (\ x -> e) $ v = v & (\ x -> e)

do { r c) =<< m = m >>= (\ r -> c)

哪里

(&) :: a -> (a -> b) -> b

(&) = flip ($)

infixl 0 &

保护功能已定义

guard :: Additive m => Bool -> m ()

guard True = return ()

guard False = fail

其中单元类型或“空的元组”

data () = ()

可以使用类型类抽象化支持选择和失败的加法蒙纳德

class Monad m => Additive m where

fail :: m t

() :: m t -> m t -> m t

infixl 3

instance Additive Maybe where

fail = Nothing

Nothing m = m

m _ = m

instance Additive [] where

fail = []

() = (++)

其中fail并形成一幺forall k l m.

k fail = k

fail l = l

(k l) m = k (l m)

并且fail是添加单核的吸收//灭零元素

_ =<< fail = fail

如果在

guard (even p) >> return p

even p为真,则警卫队产生[()],并根据的定义>>,产生局部常数

\ _ -> return p

适用于结果()。如果为假,则后卫将生成列表monad的fail([]),将其应用于Kleisli箭头不会产生任何结果>>,因此将p其跳过。

臭名昭著的是,使用monad对状态计算进行编码。

甲状态处理器是一个函数

forall st t. st -> (t, st)

转换状态st并产生结果t。该状态 st可以是任何东西。没有任何内容,标志,计数,数组,句柄,机器,世界。

状态处理器的类型通常称为

type State st t = st -> (t, st)

状态处理程序monad是仁慈的* -> *函子State st。状态处理器monad的Kleisli箭头是函数

forall st a b. a -> (State st) b

在规范的Haskell中,定义了状态处理器monad的惰性版本

newtype State st t = State { stateProc :: st -> (t, st) }

instance Functor (State st) where

map :: (a -> b) -> ((State st) a -> (State st) b)

map f (State p) = State $ \ s0 -> let (x, s1) = p s0

in (f x, s1)

instance Monad (State st) where

return :: t -> (State st) t

return x = State $ \ s -> (x, s)

(=< (State st) b) -> (State st) a -> (State st) b

f =<< (State p) = State $ \ s0 -> let (x, s1) = p s0

in stateProc (f x) s1

通过提供初始状态来运行状态处理器:

run :: State st t -> st -> (t, st)

run = stateProc

eval :: State st t -> st -> t

eval = fst . run

exec :: State st t -> st -> st

exec = snd . run

状态访问由原语get和put,有状态单子抽象方法提供:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class Monad m => Stateful m st | m -> st where

get :: m st

put :: st -> m ()

m -> st声明状态类型对monad 的功能依赖 ; 一个,例如,将确定的状态类型是唯一。stmState tt

instance Stateful (State st) st where

get :: State st st

get = State $ \ s -> (s, s)

put :: st -> State st ()

put s = State $ \ _ -> ((), s)

与void在C中类似使用的单位类型。

modify :: Stateful m st => (st -> st) -> m ()

modify f = do

s

put (f s)

gets :: Stateful m st => (st -> t) -> m t

gets f = do

s

return (f s)

gets 通常与记录字段访问器一起使用。

状态monad等效于变量线程

let s0 = 34

s1 = (+ 1) s0

n = (* 12) s1

s2 = (+ 7) s1

in (show n, s2)

其中s0 :: Int,是同样参照透明的,但无限地更加优雅和实用

(flip run) 34

(do

modify (+ 1)

n

modify (+ 7)

return (show n)

)

modify (+ 1)是类型的计算State Int (),除了其作用等同于return ()。

(flip run) 34

(modify (+ 1) >>

gets (* 12) >>= (\ n ->

modify (+ 7) >>

return (show n)

)

)

结合性的莫纳德定律可以写成 >>= forall m f g.

(m >>= f) >>= g = m >>= (\ x -> f x >>= g)

要么

do { do { do {

r1

r0

f r0 r1

}; g r1 }

g r1 }

} }

像面向表达式的编程(例如Rust)一样,块的最后一条语句表示其产量。绑定运算符有时称为“可编程分号”。

一元模拟来自结构化命令式编程的迭代控制结构原语

for :: Monad m => (a -> m b) -> [a] -> m ()

for f = foldr ((>>) . f) (return ())

while :: Monad m => m Bool -> m t -> m ()

while c m = do

b

if b then m >> while c m

else return ()

forever :: Monad m => m t

forever m = m >> forever m

输入输出

data World

I / O世界状态处理器monad是纯Haskell与现实世界,功能性说明性和命令性操作语义的协调。与实际严格执行的近似:

type IO t = World -> (t, World)

不纯净的原语促进了交互

getChar :: IO Char

putChar :: Char -> IO ()

readFile :: FilePath -> IO String

writeFile :: FilePath -> String -> IO ()

hSetBuffering :: Handle -> BufferMode -> IO ()

hTell :: Handle -> IO Integer

. . . . . .

使用IO原语的代码的杂物由类型系统永久地协议化。因为纯净真棒,所以发生在里面IO,留在里面IO。

unsafePerformIO :: IO t -> t

或者至少应该如此。

Haskell程序的类型签名

main :: IO ()

main = putStrLn "Hello, World!"

扩展到

World -> ((), World)

改变世界的功能。

结语

类别对象是Haskell类型,而态态是Haskell类型之间的函数,类别为“快速和宽松” Hask。

函子T是从类别C到类别的映射D; 对于一个对象中C的每个对象D

Tobj : Obj(C) -> Obj(D)

f :: * -> *

并且对于一个态中C的每个态D

Tmor : HomC(X, Y) -> HomD(Tobj(X), Tobj(Y))

map :: (a -> b) -> (f a -> f b)

其中X,Y在对象C。HomC(X, Y)是同态类的所有态射的X -> Y在C。仿函数必须保留态射特性和组合物,所述的“结构” C中D。

Tmor Tobj

T(id) = id : T(X) -> T(X) Identity

T(f) . T(g) = T(f . g) : T(X) -> T(Z) Composition

该Kleisli类一类C是由Kleisli三重给定

终结者的

T : C -> C

(f),身份同构eta(return)和扩展运算符*(=<

每个Kleisli态 Hask

f : X -> T(Y)

f :: a -> m b

由扩展运营商

(_)* : Hom(X, T(Y)) -> Hom(T(X), T(Y))

(=< m b) -> (m a -> m b)

在Hask的Kleisli类别中被赋予了态射

f* : T(X) -> T(Y)

(f =< m b

克莱斯里(Kleisli)类别的构成以.T扩展名给出

f .T g = f* . g : X -> T(Z)

f <=< g = (f =< m c

并满足类别公理

eta .T g = g : Y -> T(Z) Left identity

return <=< g = g :: b -> m c

f .T eta = f : Z -> T(U) Right identity

f <=< return = f :: c -> m d

(f .T g) .T h = f .T (g .T h) : X -> T(U) Associativity

(f <=< g) <=< h = f <=< (g <=< h) :: a -> m d

应用等价转换

eta .T g = g

eta* . g = g By definition of .T

eta* . g = id . g forall f. id . f = f

eta* = id forall f g h. f . h = g . h ==> f = g

(f .T g) .T h = f .T (g .T h)

(f* . g)* . h = f* . (g* . h) By definition of .T

(f* . g)* . h = f* . g* . h . is associative

(f* . g)* = f* . g* forall f g h. f . h = g . h ==> f = g

在扩展方面被规范地给出

eta* = id : T(X) -> T(X) Left identity

(return =< m t

f* . eta = f : Z -> T(U) Right identity

(f =< m d

(f* . g)* = f* . g* : T(X) -> T(Z) Associativity

(((f =< m c

也可以mu在编程中称为Monad,而不是根据Kleislian扩展定义而是自然转换join。monad被定义mu为Cendofunctor 的category 的三元组

T : C -> C

f :: * -> *

和两个自然转变

eta : Id -> T

return :: t -> f t

mu : T . T -> T

join :: f (f t) -> f t

满足等价

linux中的baast参数是什么,什么是monad?相关推荐

  1. linux中du命令参数的用法,linux中du命令参数及df命令和dd命令介绍

    本文详细介绍了linux中du命令参数及df命令和dd命令的使用方法,并对之进行了举例说明. linux中df命令参数 linux中df命令参数功能:检查文件系统的磁盘空间占用情况.可以利用该命令来获 ...

  2. Linux中ifcfg-eth0配置参数解释

    Linux中设置IP地址经常使用到ifcfg-eth0这个文件.  vi /etc/sysconfig/network-scripts/ifcfg-eth0 附录文件中的内容: DEVICE=eth0 ...

  3. linux中 tar 报参数列表过长,四种解决”Argument list too long”参数列表过长的办法...

    在linux中删除大量文件时,直接用rm会出现:-bash: /bin/rm: 参数列表过长,的错误. 这时可以用find命令来结合使用. 例: 1.rm * -rf 改为: find . -name ...

  4. 如何查看Linux中的内存参数?

    平时工作中也会查看一些系统的内存指标,但对一些参数的具体含义不太清楚,这里记录下常见参数的含义. 平时我们看的比较多的可能是通过top命令显示的内存指标 上面的图中和程序内存相关的列主要是三列: VI ...

  5. Linux中高斯分布的参数设置,华为openGauss 配置操作系统参数

    openGauss要求各主机上的操作系统参数设置成一定的值,以满足系统运行的性能要求等. 这些参数有些会在openGauss安装环境准备阶段完成设置,且这些参数将直接影响openGauss的运行状态, ...

  6. linux中fdisk的参数,Linux fdisk命令参数及用法详解--Linux磁盘分区管理命令fdisk

    fdisk 命令 linux磁盘分区管理 用途:观察硬盘之实体使用情形与分割硬盘用. 使用方法: 一.在 console 上输入 fdisk -l /dev/sda ,观察硬盘之实体使用情形. 二.在 ...

  7. Linux中top命令参数详解、常用快捷键

    1.命令 1.简介 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.  显示系统当前的进程和其他状况: top是一个动态显示过程 ...

  8. windows中探测计算网络的MTU值,window中ping命令参数和Linux中ping命令参数

    索引 探测路由wan口MTU值方法: window中使用ping命令添加的参数信息 Linux系统下ping指令的格式及参数 如何探测window的MTU值,批处理之路由MTU值探测 探测路由wan口 ...

  9. linux 中 top 命令参数详解

    top命令用法 top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况. top的使用方式 top [-d number] | top [-bnp] ...

最新文章

  1. 【讲人话】Angular如何通过@ViewChildren获取实时渲染的动态DOM节点元素(@ViewChild只能获取静态的固定DOM节点)
  2. 读书笔记|如何让用户为你的产品尖叫
  3. chrome 跨域插件
  4. java 链表反转_LeetCode206 实现单链表的反转
  5. 域用户绑定计算机批量设置,Windows 2008 AD域账户与计算机名批量绑定
  6. 鸿蒙系统发红包,鸿蒙修真录红包版
  7. 牛客网_PAT乙级_1023旧键盘打字(20)【别人代码里用到的hash是啥】
  8. PowerDesigner(1)----转载
  9. 动手学无人驾驶(4):基于激光雷达点云数据3D目标检测
  10. vue 各组件 使用 Demo
  11. Foxmail邮件字体大小怎么设置 Foxmail字体的设置方法
  12. 理想制动力分配曲线matlab源代码_电动汽车机电复合制动力分配策略
  13. 批处理设置服务器BIOS序列号,批处理设置windows服务器的代码ThecSafe1.9.4第1/3页
  14. 【数据可视化】使用pyecharts绘制南丁格尔玫瑰图和水平堆叠条形图
  15. Android NavigationView中设置menu中的item字体颜色
  16. 用阿里云盘,找不到资源怎么办???
  17. 表单获取焦点和失去焦点
  18. coj #10066新的开始(最小生成树)
  19. PythonScript_003_通过Cookie模拟登陆人人网
  20. Aggressive cows-疯牛POJ(2456)-详解

热门文章

  1. 国际观察013 | 什么?快速路变身景观大道竟不影响交通?--听巴黎规划专家给你讲...
  2. iv+css大作业:主题旅游网站设计——蓝色主题旅游网页设计(6页) HTML+CSS+JavaScript 主题出行
  3. python中创建一个字典的语句_Python 字典(dict)介绍
  4. clip-path介绍
  5. html旋转的等到的圆圈,CSS3 Loading 旋转圆盘加载动画
  6. 一种基于浏览器的自动小票机打印实现方案(js版)
  7. windows 10企业版 专业版 家庭版集合 远程桌面连接提示出现身份验证错误,要求的函数不受支持。
  8. 深入理解Java枚举类型(enum)(4)
  9. 计算机的设计原则和,设计原则“词典”|104个设计原则(上)
  10. Lock锁的方法使用