简体   繁体   English

Monad法律适用于基于应用的公式

[英]Monad laws for an applicative-based formulation

Normally in Haskell we define Monad s in terms of return and >>= . 通常在Haskell中我们用return>>=来定义Monad s。 Sometimes it's convenient to decompose >>= into fmap and join . 有时将>>=分解为fmapjoin是很方便的。 The Monad laws for these two formulations are well known and fairly intuitive, once you get used to them. 一旦你习惯了这两种配方的Monad法则是众所周知的并且相当直观。

There's another way to define monads, in terms of an Applicative functor: 根据Applicative仿函数,还有另一种定义monad的方法:

class Applicative f => MyMonad f where
    myJoin :: f (f a) -> f a

I'm wondering about the laws for this kind of formulation. 我想知道这种配方的法律。 Obviously, we could just adapt the fmap + join laws, as follows (I am not sure the names are particularly apt, but oh well): 显然,我们可以调整fmap + join法则,如下所示(我不确定这些名称是否特别fmap ,但是很好):

myJoin . myJoin = myJoin . (pure myJoin <*>)       ('Associativity')
myJoin . pure   = myJoin . (pure pure   <*>) = id  ('Identity')

Clearly these conditions are sufficient for pure , (<*>) , and myJoin to form a monad (in the sense that they guarantee that m `myBind` f = myJoin (pure f <*> m) will be a well-behaved >>= ). 很明显,这些条件对于pure (<*>)myJoin足以构成一个monad(从某种意义上说,他们保证m `myBind` f = myJoin (pure f <*> m)将是一个表现良好的>>= )。 But are they necessary as well? 但它们也是必要的吗? It seems at least possible that the additional structure that Applicative supports above and beyond Functor might allow us to simplify these laws -- in other words, that some feature of the above laws might be otiose given that it is known that pure and (<*>) already satisfy the Applicative laws. 至少有可能的是, Applicative支持以上和Functor之外的其他结构可能允许我们简化这些法则 - 换句话说,上述法律的某些特征可能是非常的,因为已知pure(<*>)已满足Applicative法律。

(In case you're wondering why we'd even go to the trouble of bothering with this formulation given either of the two standard possibilities: I'm not sure it's all that useful or perspicuous in programming contexts, but it turns out to be so when you use Monad s to do natural langauge semantics .) (如果你想知道为什么我们甚至会遇到困扰这个公式的两种标准可能性:我不确定它在编程环境中是否有用或显而易见,但事实证明是所以当你使用Monad s 做自然语言语义时 。)

The identity law is much easier to write 身份法更容易编写

join . fmap pure = join . pure = id

The traditional monad right identity law follows immediately from the definition of >>= . 传统的monad权利身份法立即遵循>>=的定义。 The left identity law uses an Applicative law 左侧身份法使用Applicative法律

m >>= k = join (fmap k m)

-- proof for right identity
m >>= return       = m
join (fmap pure m) = m  -- definition of >>=
id m               = m  -- identity
m                  = m  -- definition of id

-- proof for left identity
return a >>= f         = f a
join (fmap f (pure a)) = f a  -- definitions of >>= and return
join (pure (f a))      = f a  -- fmap f . pure = pure . f
id (f a)               = f a  -- identity
f a                    = f a  -- definition of id

The interesting law for a relationship between Applicative and Monad is ApplicativeMonad之间关系的有趣法则是

(<*>) = ap
-- or
m1 <*> m2 = m1 >>= (\x1 -> m2 >>= \x2 -> return (x1 x2)) -- definition of ap

In terms of Applicative and join this is Applicativejoin方面,这是

m1 <*> m2 = join (fmap (\x1 -> fmap x1 m2) m1)
-- proof
m1 <*> m2 = join (fmap (\x1 -> m2 >>= \x2 -> return (x1 x2)) m1)            -- definition of ap
m1 <*> m2 = join (fmap (\x1 -> join (fmap (\x2 -> return (x1 x2)) m2)) m1)  -- definition of >>=
m1 <*> m2 = join (fmap (\x1 -> join (fmap (\x2 -> pure (x1 x2)) m2)) m1)    -- return = pure
m1 <*> m2 = join (fmap (\x1 -> join (fmap (pure . x1) m2)) m1)                 
m1 <*> m2 = join (fmap (\x1 -> join (fmap pure (fmap x1 m2))) m1)           -- fmap (f . g) = fmap f . fmap g
m1 <*> m2 = join (fmap (\x1 -> fmap x1 m2) m1)                              -- identity

There might be a more elegant way to write this. 可能有更优雅的方式来写这个。

I haven't found a way to show that the Monad is associative based on 我还没有找到一种方法来表明Monad是基于联想的

  • Functor and Applicative laws - particularly composition of <*> FunctorApplicative Functor - 特别是<*>
  • The identities join . fmap pure = join . pure = id 身份join . fmap pure = join . pure = id join . fmap pure = join . pure = id
  • (<*>) = ap

and I'm not sure if it's true. 我不确定这是不是真的。 I think you need the associative law join . join = join . fmap join 我认为你需要联想法join . join = join . fmap join join . join = join . fmap join

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM