长话短说,我在看西蒙·佩顿·琼斯的演讲,在21:41的时候,他引用了一句话:
我当时正在处理一个bug,很沮丧,在ghci中输入了“修复错误”…
我试过了。
结果:
λ> import Data.Function -- here is fix
λ> fix error
"*** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: and goes on like this towards infinity
一开始我只是想,这个fix
到底做了什么?
所以我看了一些类型
λ> :t error
error :: [Char] -> a
λ> :t fix
fix :: (a -> a) -> a
因此
λ> :t fix error
fix error :: [Char]
但很明显,这仍然没有告诉我多少结果。
然而,更奇怪的是,即使是take 10$fix error
或length$take 10$fix error
的输出也和上面的一样是一个永不间断的输出(除了后者的输出,length…
,缺少首字母“
)。
我在看什么?
需要明确的是,目前我仍然不太了解关于黑客的文档。并不是说我花了超过3分钟的时间,但我仍然迷失在第一行。
它会产生错误(error(error(error…))
。因为错误
的类型为[Char]-
为什么也
拿10$修复错误
也一样?
因为它在获取列表的前10个元素时也会出错,因为评估列表会引发错误,并且在打印异常时,将开始相同的行为。
因此,它永远不会生成
Char
s列表:它会引发一个错误,并开始打印错误消息,而不是返回它。
fix
计算函数的固定点;固定点是一个可以提供给函数的值,它将产生与结果完全相同的值。
例如,如果您有函数f_="hello"
(或const"hello"
),则此函数的固定点是字符串"hello"
。事实上修复f
是"hello"
。
许多函数都有多个固定点,因此fix
的文档需要指定返回哪个固定点。例如:
g :: Integer -> Integer
g x
| even x = x
| otherwise = x + 1
每个偶数都是g
的固定点,但fix g
promise(按其类型)是一个特定的整数。哪一个?
文档中说,
fix
产生的固定点最少,并进一步阐明,这意味着输入函数的固定点定义的值最少。请注意,“最小定义”并不是指定义的最小值,而是指具有最小“定义性”的值。在非正式意义上,这是一个技术领域,我并没有像我希望的那样处于最顶端:像1::Integer
,True
,(
,只是'a'
等完全定义的值,因为您可以在不出错的情况下对它们进行全面评估。底部值(未定义
,让x=x在x中
等)完全未定义。中间是像1:2:undefined
这样的值,在这些值中,您可以查看某些结构,而不会遇到错误,但内部某处有一个底部。
因此,
fix g
只是底部(当我尝试时,GHC检测到一个无限循环并中止了它),因为g undefined
是一个错误(所有底部都是“相同的值”)。
事实证明,在使用
fix
时编写的大多数简单函数都是如此。对于任何严格函数(以任何方式检查其参数的函数),bottom将是一个不动点,这就是fix
将要计算的那个。那么我们为什么要关心它呢?
fix
在理论上很有意义,因为你可以用它在一种缺乏直接支持的语言中实现递归。在这样的递归定义中:
sum :: [Integer] -> Integer
sum [] = 0
sum (x : xs) = x + sum xs
事实上有一些令人印象深刻的事情正在发生。您正在定义
sum
,但sum
在其自身定义的范围内。实现该功能比编译只使用预先存在的定义的定义要困难一些。让我们想象一下,我们无法做到这一点,但我们仍然希望编写sum
。你可以这样做:
sum' :: ([Integer] -> Integer) -> [Integer] -> Integer
sum' _ [] = 0
sum' rec (x : xs) = x + rec xs
sum = fix sum'
现在,每个定义都只使用以前定义过的东西;没有自我参照。与直接调用自身不同,
sum'
接收一个额外的参数,该参数是它应该在列表尾部调用的函数。该函数参数必须具有我们最初想要给出的sum
类型,这使得sum'
类型成为a的一个实例-
它这样做的方式是通过生成形式
sum'(sum'(sum'(sum'...))
的“无限嵌套”表达式(这基本上是它找到任何函数不动点的方式;答案已经变得相当长了,所以我不会在这里详细说明为什么它会起作用)。每个sum'
都会收到一个参数,该参数说明如何处理列表的尾部;该参数本身就是对sum'
的另一个调用,它需要一个参数说明如何处理原始列表尾部的尾部,该参数是对sum'
的另一个调用,依此类推。最终(如果列表是有限的)我们找到了空列表的基本情况,不需要下一级嵌套的sum'
调用,因此嵌套表达式没有尽头并不重要!(显然,这在急切评估的语言中不起作用)
事实证明,这是一种通用模式,您可以将直接递归转换为
fix
的使用。
这么说吧,希望你能明白为什么
fix error
会这样。Willem Van Onsem的答案在这里很好,所以我不会详细重复。但是基本上,fix error
必须产生一个字符串s
,这样error s
就相当于s
。当然,这对于任何非底部字符串都是不可能的,因为error
总是产生底部(这就是它的全部意义),所以fix error
必须是某种形式的底部。在搜索固定点时,它会生成一个无限嵌套的表达式error(error(error…)
,当GHC打印错误消息时,它本身会生成一个错误,而该错误消息是另一个错误,等等,您看到的是生成的输出。
问题内容: 作为开发人员,我与E_NOTICE一起工作。不过最近,有人问我为什么应该修复E_NOTICE错误。我能提出的唯一理由是纠正这些问题的最佳实践。 还有其他人有任何理由证明纠正这些问题所花费的额外时间/成本吗? 更具体地说,如果代码已经起作用,为什么经理应该花钱修复这些问题? 问题答案: 摘要 在PHP运行时配置文件给你一些想法,为什么: 在开发过程中启用E_NOTICE有一些好处。 出于
我有一些代码,当我运行它时会产生一个错误,说: NoSuchMethod:对null调用了方法“XYZ” 这意味着什么?我该如何修复它?
为什么字段resultsqueue的修饰符重复?即使当我将resultQueue名称更改为每隔一个名称时,仍然会得到这个错误。当我在main函数中移动resultsQueue时,我不会得到这个错误。 这是我的代码:
问题内容: 我见过人们在HTML元素上应用CSS属性。 他们为什么这样做,并且可以解决什么错误? 问题答案: 这提供了一个内部属性,在Internet Explorer 7及更低版本中被称为。 可以通过给元素“布局”来解决许多Internet Explorer的呈现不一致问题。在本文中,作者重点研究了这一复杂问题的某些方面。 “布局”是IE / Win专有的概念,它确定元素如何绘制和绑定其内容,与
在一个create-react-app typescript项目中,我试图编写这个只是为了快速测试一些东西: 但它给了我以下错误,有一个红色的波浪线: 当提供'-隔离模块'标志时,所有文件都必须是模块。 但是,如果我将文件更改为以下内容,那么一切显然都很好(当然除了未使用的导入): 为什么?这里发生了什么事?< code> - isolatedModules实际上是什么意思/做什么?
我需要将12小时的时间转换为24小时的格式。 我现在已经把12小时的时间硬编码了,以使事情更简单。 我的逻辑:输入sting 07:05:45PM提取最后2个字符。如果AM check为前两个字符,则为12。。如果是,则将其设置为00,否则按原样输出,如果PM检查前两位数字是否为12。。如果是,请保持原样,如果不是,则在前2位加上12 总线错误:10是我运行代码得到的