linux中的baast参数是什么,什么是monad?

小智..

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

满足等价

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值