- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Haskell 中实现按值调用 lambda 演算时,我是否应该强制对对象语言中函数的参数求值(即按值调用 lambda 演算)来绕过调用 -元语言(即 Haskell)的按需求值顺序?
具体来说,对于下面使用高阶抽象语法的实现:
data Exp
= Abs (Exp -> Exp)
| App Exp Exp
eval :: Exp -> Exp
eval exp = case exp of
Abs _ -> exp
App opr opd -> case eval opr of
Abs fun -> eval (fun $ eval opd) -- argument evaluation
在有评论的那一行,我是否应该使用 fun $! eval opd
代替?
我知道对象和元级别之间的评估顺序依赖可以通过 CPS 转换来避免。但我暂时不想打扰它。我就要确保在 Haskell 中忠实地实现按值调用。我提出这个问题是因为我看到的许多示例实现似乎都没有考虑到这一点。我是说这些实现不会强制执行 eval opd
。不知是他们疏忽了,还是我想多了。谢谢。
最佳答案
在这里使用 $!
确实有效,只要在元语言中将 eval e
评估为弱头部范式对应于评估 e
到对象语言中的值。
让我通过向 Exp
数据类型添加一个新的构造函数来表示一个发散计算,以及一个我们可以实际打印的值来证明这一点:
data Exp
= Abs (Exp -> Exp)
| App Exp Exp
| Bot
| Value
printExp :: Exp -> String
printExp Bot = "bottom"
printExp Value = "base value"
printExp (Abs _) = "function"
printExp (App _ _) = "thunk"
为简单起见,我们将其转换为对评估函数中的 error
的调用。
eval :: Exp -> Exp
eval exp = case exp of
Bot -> error "Evaluation would not terminate "
Value -> Value
Abs _ -> exp
App opr opd -> case eval opr of
Abs fun -> eval (fun $ eval opd)
现在我们可以看看这是否是按值调用。下面的代码应该发散,因为我们将 bottom 传递给一个函数。唉,它没有:
*Main> let e = App (Abs (\_ -> Value)) Bot
*Main> printExp e
"thunk"
*Main> printExp (eval e)
"base value"
将 $
更改为 $!
有帮助吗?是的,确实如此:
*Main> let e = App (Abs (const Value)) Bot
*Main> printExp (eval e)
"*** Exception: Evaluation would not terminate
但这有多可靠?必须仔细检查对 Exp
数据类型的任何更改,以查看是否强制最外层构造函数是您想要的,例如引入对。
使用 deepseq
可能更可靠一点,即 $!!
。但我真正建议的是添加一个 isValue::Exp -> Bool
谓词,明确检查参数是否是对象语言的基值,并检查 isValue (eval opd)
在调用 fun
之前在 eval
中。
关于haskell - 在 Haskell 中实现按值调用 lambda 演算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14455958/
(图1) 简单类型 lambda 演算的一部分(图 1),它在 Haskell 中实现,如下所示。 evaluate expression = do case expression
在 Tom Stuart 的《Understanding Computation》一书中,有一章专门介绍通过 Procs/Lambdas 重建 FizzBuzz。他首先讨论了如何通过过程定义数字,
在 lambda 演算中 (λ x. λ y. λ s. λ z. x s (y s z)) 用于添加两个 Church 数字,我们如何解释这一点,是否有用于函数式编程的 lambda 演算的任何好的
好的,所以我正在尝试实现 basics of lambda calculus .就到这里了。 我的号码: def zero[Z](s: Z => Z)(z: Z): Z = z def one[Z](
我一直在尝试在 C# 上实现原始 lambda 演算,但在实现它时遇到了一些麻烦,因为最后,我总是被要求提供对象。 例如,我想要一些可以让我定义一些基本逻辑组合子的东西,例如 I = Lambda x
我在 Haskell 编程中的冒险并不都是史诗般的。我正在实现简单的 Lambda 演算,我很高兴完成了语法、评估以及替换,希望它们是正确的。剩下的就是红色框中定义的打字(如下图所示),我正在寻找指导
如何扩展简单类型的 lambda 演算以拥有支持类似 monad 类型的类型系统?基本上,我目前对简单类型的 lambda 演算有了很好的理解,并且我想了解将 monad 添加到该基础的“最低要求”。
在 lambda 演算中,如果一个项具有范式,则正常的降阶策略将始终产生它。 我只是想知道如何严格证明上述命题? 最佳答案 您提到的结果是所谓的标准化定理的推论,指出对于任何归约序列 M->N,在相同
在 OCaml 中,“fun”似乎是我的绑定(bind)运算符。 OCaml 有内置替换吗?如果有,它是如何实现的?它是使用 de Bruijn 索引实现的吗? 只是想知道如何在 OCaml 中实现无
在 Haskell 中实现按值调用 lambda 演算时,我是否应该强制对对象语言中函数的参数求值(即按值调用 lambda 演算)来绕过调用 -元语言(即 Haskell)的按需求值顺序? 具体来说
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
为什么纯无类型 lambda 演算经常被描述为无法使用? 有了合适的函数库,它会不会与任何其他函数式语言大致相同? 最佳答案 速度不是大问题。例如,您可以决定使用教堂数字但优化实现,以便像往常一样表示
我正在将一些我在 python 中制作原型(prototype)的代码移植到闪存中,而 actionscript 并没有我预期的那么糟糕(我听说 v3 比 v2 好很多!)我还有一些东西这样做似乎过于
有人告诉我这个词 (z (λy.z x) (λy.y z)) 已经是正常形式了——但我不明白为什么。不能在这种状态下进行另一个 beta 缩减,并将术语 (λy.z x) 中所有出现的 y 替换为 (
Haskell 和 Lambda 演算中的 Python 代码是什么? def f1(): x = 77 def f2(): print x f2 f1 我在 lambd
我想用不同的编程语言实现 bool 值和 NOT 运算符的 lambda 演算构造。 它们是: TRUE = lx.ly. x FALSE = lx.ly. y NOT = lx. x FALSE T
使用 JavaScript。让我们定义以下内容: M = f => f(f) // Mocking Bird I = a => a // Identity 假设现在我们写这个表达式 M( f =>
我一直在玩 javascript(节点)中的 lambda 演算。 我创建了一些 Church 数字,并且一直在尝试创建一个计算斐波那契数列的递归函数,但它绝对行不通! 我曾尝试将函数包装在 Y 组合
我必须为 > 、 , != 编者注:我认为这就是 OP 试图提出的问题: 我正在尝试使用 Church 编码在无类型 lambda 演算中实现以下操作: 大于(GT 或 >)。 小于(LT 或 、
可以解释 Haskell 中的 lambda 演算: data Expr = Var String | Lam String Expr | App Expr Expr data Value a = V
我是一名优秀的程序员,十分优秀!