申请人撰写,monad没有

mis*_*tor 104 monads haskell functional-programming monad-transformers applicative

申请人撰写,monad没有.

上述陈述是什么意思?什么时候比其他人更好?

pig*_*ker 111

如果我们比较类型

(<*>) :: Applicative a => a (s -> t) -> a s -> a t
(>>=) :: Monad m =>       m s -> (s -> m t) -> m t
Run Code Online (Sandbox Code Playgroud)

我们得到了两个概念分开的线索.这(s -> m t)在类型(>>=)显示,在值s可以确定在计算中的行为m t.Monad允许值和计算层之间的干扰.该(<*>)运营商允许没有这样的干扰:功能和参数的计算不依赖于价值.这真的很棒.相比

miffy :: Monad m => m Bool -> m x -> m x -> m x
miffy mb mt mf = do
  b <- mb
  if b then mt else mf
Run Code Online (Sandbox Code Playgroud)

它使用某种效果的结果来决定两次计算(例如发射导弹和签署停战协定),而

iffy :: Applicative a => a Bool -> a x -> a x -> a x
iffy ab at af = pure cond <*> ab <*> at <*> af where
  cond b t f = if b then t else f
Run Code Online (Sandbox Code Playgroud)

它使用值在两个计算的值ab之间进行选择,并且已经执行了两个计算,也许是为了悲剧效果.ataf

monadic版本主要依赖于(>>=)从值中选择计算的额外功能,这可能很重要.然而,支持这种力量使得monad难以构成.如果我们试图建立'双重绑定'

(>>>>==) :: (Monad m, Monad n) => m (n s) -> (s -> m (n t)) -> m (n t)
mns >>>>== f = mns >>-{-m-} \ ns -> let nmnt = ns >>= (return . f) in ???
Run Code Online (Sandbox Code Playgroud)

我们到目前为止,但现在我们的层都混乱了.我们有一个n (m (n t)),所以我们需要摆脱外在的n.正如Alexandre C所说,如果我们有合适的话,我们就可以做到

swap :: n (m t) -> m (n t)
Run Code Online (Sandbox Code Playgroud)

n内部和内部置换join到另一个n.

较弱的"双重应用"更容易定义

(<<**>>) :: (Applicative a, Applicative b) => a (b (s -> t)) -> a (b s) -> a (b t)
abf <<**>> abs = pure (<*>) <*> abf <*> abs
Run Code Online (Sandbox Code Playgroud)

因为层之间没有干扰.

相应地,当你真正需要Monads 的额外功能时,以及当你可以摆脱Applicative支持的刚性计算结构时,这是很好的.

顺便说一下,虽然编写monad很困难,但它可能比你需要的更多.类型m (n v)表示计算与m效果- ,然后与计算n效果-到v-值,其中,所述m效果-完成之前n效果-启动(因此为需要swap).如果你只是想mn-effects 交错-effects ,那么组合可能太多了!

  • 你仍然得到两者的*效果*,但纯粹(错误"坏")没有任何.另一方面,如果你尝试iffy(纯真)(纯"你好")(错误"坏"),你会得到一个miffy避免的错误.此外,如果你尝试iffy(纯真)(纯0)[1,2]之类的东西,你将获得[0,0]而不是[0].应用程序对它们有一种严格的要求,因为它们构建了固定的计算序列,但正如您所观察到的那样,由这些计算产生的*值*仍然懒惰地组合在一起. (5认同)
  • 这种变形金刚经常存在,但据我所知,没有规范的方法可以产生它们.关于如何从不同的monad中解析交错效果通常是一个真正的选择,经典的例子是异常和状态.异常是否应该回滚状态变化?两种选择都有自己的位置.话虽如此,有一个"自由monad"的东西,表达"任意交错".`data Free fx = Ret x | Do(f(Free fx))`,然后`data(:+ :) fgx = Inl(fx)| Tnr(gx)`,并考虑`Free(m:+:n)`.这延迟了如何运行交错的选择. (4认同)
  • 对于iffy示例,您声明它"使用ab的值来选择at和af两个计算的值,同时执行两者,也许是悲剧效应." 难道Haskell的懒惰本质不能保护你免受这种侵害吗?如果我有list =(\ btf - > if b then t else f):[]然后执行语句:list <*> pure True <*> pure"hello"<*> pure(错误"bad"). ...我得到"你好",错误永远不会发生.这个代码并不像monad那样安全或受控制,但这个帖子似乎表明应用程序会导致严格的评估.虽然整体很棒!谢谢! (3认同)

Con*_*nal 72

申请人撰写,monad没有.

Monads 确实组成,但结果可能不是monad.相反,两种应用的组合物必然是一种应用.我怀疑原始陈述的意图是"应用性构成,而monadness不构成." 改写," Applicative在成分下关闭,而Monad不是."

  • 另外,任何两种应用以完全机械的方式组成,而由两种单子的组合形成的单子对该组合物是特定的. (24认同)
  • 另外monad以其他方式构成,两个monad的产品是monad,只有副产品需要某种分配规律. (11认同)

Rot*_*sor 38

如果你有applicatives A1A2,那么该类型data A3 a = A3 (A1 (A2 a))也是应用性(你可以写在一个通用的方法这种情况下).

在另一方面,如果你有单子M1M2那么该类型data M3 a = M3 (M1 (M2 a))不一定是单子(不存在用于明智的通用实现>>=join该组合物).

一个例子可以是类型[Int -> a](在这里我们撰写类型构造[](->) Int,这两者都是单子).你可以轻松写作

app :: [Int -> (a -> b)] -> [Int -> a] -> [Int -> b]
app f x = (<*>) <$> f <*> x
Run Code Online (Sandbox Code Playgroud)

这可以概括为任何应用:

app :: (Applicative f, Applicative f1) => f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)
Run Code Online (Sandbox Code Playgroud)

但是没有合理的定义

join :: [Int -> [Int -> a]] -> [Int -> a]
Run Code Online (Sandbox Code Playgroud)

  • @andrew,如果你的意思是仿函数,那么是的,仿函数更简单,应该在足够的时候使用.请注意,并非总是如此.例如,没有'Monad`的`IO`将很难编程.:) (2认同)

Lan*_*dei 17

不幸的是,我们真正的目标,monad的组成,更加困难...事实上,我们实际上可以证明,在某种意义上,没有办法只使用两个monad的操作来构造具有上述类型的连接函数(参见附录中的证明大纲).因此,我们可能希望形成一个组合的唯一方法是,如果有一些额外的结构连接这两个组件.

撰写monad,http: //web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf

  • 要编写`swap :: N(M x) - > M(N x)`它看起来像你可以使用`returns`(适当的`fmap`ped)在前面插入一个`M`和一个`N `在后面,从'N(M x) - > M(N(M(N x)))`开始,然后使用复合的`join`得到你的'M(N x)`. (7认同)
  • Tl;博士为不耐烦的读者:如果(f?)你可以提供一个自然的转换`swap:NM a - > MN a`你可以组成monad (4认同)

小智 7

分配法解决方案l:MN - > NM就足够了

保证NM的一致性.要看到这个,你需要一个单元和一个单元.我将专注于mult(单位是unit_N unitM)

NMNM - l -> NNMM - mult_N mult_M -> NM
Run Code Online (Sandbox Code Playgroud)

这并不能保证MN是monad.

然而,当你有分配法律解决方案时,关键的观察就会发挥作用

l1 : ML -> LM
l2 : NL -> LN
l3 : NM -> MN
Run Code Online (Sandbox Code Playgroud)

因此,LM,LN和MN是单子.问题出现在LMN是否是一个monad(或者是

(MN)L - > L(MN)或N(LM) - >(LM)N

我们有足够的结构来制作这些地图.然而,正如Eugenia Cheng所观察到的,我们需要一个六边形条件(相当于Yang-Baxter方程的表示)来保证任一构造的单一性.实际上,在六边形条件下,两个不同的单子重合.

  • 这可能是一个很好的答案,但它在我脑海中who**. (8认同)