- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据 Control.Arrow
文档,对于许多 monads(那些 >>=
操作是严格的)instance MonadFix m => ArrowLoop (Kleisli m)
不满足 loop (f >>> first h) = loop f >>> h
所要求的右紧律 ( ArrowLoop
)类(class)。为什么呢?
最佳答案
这是一个多方面的问题,有几个不同的角度,它可以追溯到 Haskell 中的值递归 ( mfix
/mdo
)。见 here背景信息。我将在这里详细讨论右紧缩问题。
mfix 的右拧紧
这是 mfix
的右拧紧属性:
mfix (λ(x, y). f x >>= λz. g z >>= λw. return (z, w))
= mfix f >>= λz. g z >>= λw. return (z, w)
mfix
表示。和值递归。如
Section 3.1 of this work所示,对于带有严格绑定(bind)运算符的 monad,您总是可以编写一个表达式来区分此等式的左侧和右侧,从而使此属性失败。 (有关 Haskell 中的实际示例,请参见下文。)
mfix
的 monad 创建时,对应
loop
运算符以相同的方式使相应的属性失败。
g
以来产生的递归值进行操作。位于“循环”内,因此能够干扰定点计算。这是一个实际的 Haskell 程序来说明:
import Control.Monad.Fix
f :: [Int] -> IO [Int]
f xs = return (1:xs)
g :: [Int] -> IO Int
g [x] = return x
g _ = return 1
lhs = mfix (\(x, y) -> f x >>= \z -> g z >>= \w -> return (z, w))
rhs = mfix f >>= \z -> g z >>= \w -> return (z, w)
lhs
它永远不会终止,而
rhs
将按预期为您提供 1 的无限列表:
*Main> :t lhs
lhs :: IO ([Int], Int)
*Main> lhs >>= \(xs, y) -> return (take 5 xs, y)
^CInterrupted.
*Main> rhs >>= \(xs, y) -> return (take 5 xs, y)
([1,1,1,1,1],1)
mdo
- 表示法呈现的此示例,这可能更易于阅读。)
Maybe
,
List
,
IO
,或任何其他基于具有多个构造函数的代数类型的 monad。
的 monad 的典型例子做 满足这个规律的是
State
和
Environment
单子(monad)。见
Section 4.10用于总结这些结果的表格。
g
上面的等式是纯的,遵循值递归定律:
mfix (λ(x, y). f x >>= λz. return (z, h z))
= mfix f >>= λz. return (z, h z)
g = return . h
.即
g
不能执行任何效果。在这种情况下,无法像您预期的那样区分左侧和右侧。结果确实来自值递归公理。 (见
Section 2.6.3 证明。)本例中的图片如下所示:
rec
keyword将决定权留给用户。
mdo
-符号和显式
do rec
,上面的例子呈现
{-# LANGUAGE RecursiveDo #-}
f :: [Int] -> IO [Int]
f xs = return (1:xs)
g :: [Int] -> IO Int
g [x] = return x
g _ = return 1
lhs :: IO ([Int], Int)
lhs = do rec x <- f x
w <- g x
return (x, w)
rhs :: IO ([Int], Int)
rhs = mdo x <- f x
w <- g x
return (x, w)
lhs
和
rhs
上面应该是一样的,但是由于右收缩律的失败,它们不是。和以前一样,
lhs
卡住了,而
rhs
成功产生值:
*Main> lhs >>= \(x, y) -> return (take 5 x, y)
^CInterrupted.
*Main> rhs >>= \(x, y) -> return (take 5 x, y)
([1,1,1,1,1],1)
f
,这证明了由
mdo
自动执行的分段是合理的-符号。
rec
符号是首选,程序员需要把它放在最少的块中以确保终止。例如,上述
lhs
的表达式应该写成这样:
lhs :: IO ([Int], Int)
lhs = do rec x <- f x
w <- g x
return (x, w)
mdo
-notation 负责解决这个问题,并将递归放置在最小块上,而无需用户干预。
mfix
在这种情况下,我们也可以为 Kleisli 箭头构建一个失败的例子。事实上,上面的例子或多或少是直接翻译的:
{-# LANGUAGE Arrows #-}
import Control.Arrow
f :: Kleisli IO ([Int], [Int]) ([Int], [Int])
f = proc (_, ys) -> returnA -< (ys, 1:ys)
g :: Kleisli IO [Int] Int
g = proc xs -> case xs of
[x] -> returnA -< x
_ -> returnA -< 1
lhs, rhs :: Kleisli IO [Int] Int
lhs = loop (f >>> first g)
rhs = loop f >>> g
mfix
的情况一样, 我们有:
*Main> runKleisli rhs []
1
*Main> runKleisli lhs []
^CInterrupted.
mfix
右旋失败IO-monad 也阻止了
Kleisli IO
箭头来自满足
ArrowLoop
中的右紧律实例。
关于haskell - 右紧 ArrowLoop 定律,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41675391/
一年多以来,我一直在阅读C++并用它编写小程序。最近我遇到了三巨头法则。我从来不知道这条法律。 无意中,我在这里找到了它:Rule of Three . 我可以知道 C++ 中的任何其他此类定律吗?
根据 Control.Arrow 文档,对于许多 monads(那些 >>= 操作是严格的)instance MonadFix m => ArrowLoop (Kleisli m)不满足 loop (
通常在 Haskell 中我们定义 Monad s 表示为 return和>>= 。有时分解也方便>>=进入fmap和join 。 Monad一旦您习惯了这两种公式的定律,它们是众所周知的并且相当直观
我正在阅读 James Iry's blog post在 Scala 中的 Monads 上。我在第三部分,我对他关于单元的单子(monad)第二定律的描述感到困惑。特别是这种说法: unit(x)
我见过提到 IO不满足单子(monad)定律,但我没有找到一个简单的例子来说明这一点。有人知道一个例子吗?谢谢。 编辑:如ertes和 n.m.指出,使用 seq有点非法,因为它可以使任何 monad
齐普夫定律是许多现实生活中的一种模式,齐普夫定律最常见的情况是在文本段落中,其中最常用的单词的数量是第二个最常用单词的两倍。 我一直在学习 Python 中的字典,并尝试自己做这件事,但对它们的一些方
这可能是一个幼稚的问题,但是 RSpec 的测试 DSL 是否违反了 Demeter 法则? 这是来自 http://rspec.info 的 RSpec DSL 示例: bowling.score.
Snell's law指出入射角和折射角的正弦比等于给定 Material 折射率比的倒数: 我想实现一个简单的程序来可视化法律。自 , 和 是已知的,这是我计算的方式 : theta2 = asin
嘿,我正在开发一个文本生成器,它应该可以生成数百万种不同的文本。为了使每篇文章的内容更真实,我使用了 Zipf 定律它运行良好,单词分布正确。 但是下面的 next() 函数执行得非常慢,因为我想生成
我正在使用一个工具来自动生成按层次结构组织的 XML 文件的类表示形式。 XML 文件是我的应用程序需要能够访问的设置文件(只读)。 如果我将顶级节点(例如,AppSettings)传递给需要访问一项
不使用形式推导,如何测试自定义的Monad实例是否遵循Monad定律? 最佳答案 FWIW,这是我最近编写的一组 QuickCheck 属性,用于测试从 F 代数派生的 Maybe 实现的 Monad
我是一名优秀的程序员,十分优秀!