【问题标题】:f, g, h :: Kleisli ((->) e) a b <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?f, g, h :: Kleisli ((->) e) a b <=> f >>> (g &&& h) = (f >>> g) &&& (f >>> h)?
【发布时间】:2019-12-19 14:11:07
【问题描述】:

编辑:如果存在这样的函数f,我们将调用一个箭头ppure:p = arr f

我正在尝试更好地掌握 Haskell 中的 Arrows,我想知道何时

f &gt;&gt;&gt; (g &amp;&amp;&amp; h) = (f &gt;&gt;&gt; g) &amp;&amp;&amp; (f &gt;&gt;&gt; h),其中fgh 是箭头。

显然,这通常不是真的。在此特定示例中,副作用在右侧重复:

GHCi> c = Kleisli $ \x -> ("AB", x + 1)
GHCi> fst . runKleisli (c >>> c &&& c) $ 1
"ABABAB"
GHCi> fst . runKleisli ((c >>> c) &&& (c >>> c)) $ 1
"ABABABAB"

显然,f &gt;&gt;&gt; (g &amp;&amp;&amp; h) = (f &gt;&gt;&gt; g) &amp;&amp;&amp; (f &gt;&gt;&gt; h) 如果f 是纯的。

我在 GHCi 中使用 f, g, h :: Kleisli ((-&gt;) e) a b 的此语句进行试验,但没有找到 fgh 的值,即 f &gt;&gt;&gt; (g &amp;&amp;&amp; h) ≠ (f &gt;&gt;&gt; g) &amp;&amp;&amp; (f &gt;&gt;&gt; h)。这个陈述对于f, g, h :: Kleisli ((-&gt;) e) a b 是否确实如此,如果是这样,这是否可以作为一个有效的证明: Monad ((-&gt;) e) 的效果是从环境中读取。因此,f 的应用结果是 gh 将从环境中读取的函数。无论这个函数是在哪里创建的——都是一样的,因为它每次都应用于同一个参数,因此从环境中读取的结果是一样的,因此总体结果也是一样的。

【问题讨论】:

  • 有趣的后续问题:哪些 monad 具有此属性?它们都同构于ReaderWriteridempotent 幺半群的组合吗?
  • @leftaroundabout 我很确定我们可以将EitherMaybe Monads 添加到列表中,因为它们的效果取决于应用程序的顺序,并且根据(&amp;&amp;&amp;) 的定义,应用程序是相同的,并且在左手和右手上的顺序相同。但我可能弄错了。你怎么看?

标签: haskell monads arrows reader-monad kleisli


【解决方案1】:

直观

是的,(-&gt;) e monad 是一个 reader monad,我们执行两次读取还是只执行一次都没有关系。运行f 一次或两次并不重要,因为它总是会产生相同的结果,具有相同的效果(读取)。

你的推理在我看来直觉上是正确的。

正式

f, g, h :: Kleisli ((-&gt;) e) a b 本质上是指f, g, h :: a -&gt; (e -&gt; b),去掉包装。

同样,忽略包装器,我们得到

for all (f :: a -> e -> b) and (g :: b -> e -> c)
f >>> g = (\xa xe -> g (f xa xe) xe)

for all (f :: a -> e -> b) and (g :: a -> e -> c)
f &&& g = (\xa xe -> (f xa xe, g xa xe))

因此:

f >>> (g &&& h)
= { def &&& }
f >>> (\xa xe -> (g xa xe, h xa xe))
= { def  >>> }
(\xa' xe' -> (\xa xe -> (g xa xe, h xa xe)) (f xa' xe') xe')
= { beta }
(\xa' xe' -> (g (f xa' xe') xe', h (f xa' xe') xe'))


(f >>> g) &&& (f >>> h)
= { def >>> }
(\xa xe -> g (f xa xe) xe) &&& (\xa xe -> h (f xa xe) xe)
= { def &&& }
(\xa' xe' -> ((\xa xe -> g (f xa xe) xe) xa' xe', (\xa xe -> h (f xa xe) xe) xa' xe'))
= { beta }
(\xa' xe' -> (g (f xa' xe') xe', h (f xa' xe') xe'))

【讨论】:

  • EitherMaybe Monads 也有这个属性吗?我相信它们会这样做,因为它们的效果取决于应用程序的顺序,并且根据(&amp;&amp;&amp;)的定义,应用程序是相同的,并且左右手的顺序相同。
  • @ZhiltsoffIgor 他们应该有,我猜。
猜你喜欢
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2014-01-22
  • 2011-07-11
相关资源
最近更新 更多