- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Haskell 编程中的冒险并不都是史诗般的。我正在实现简单的 Lambda 演算,我很高兴完成了语法
、评估
以及替换
,希望它们是正确的。剩下的就是红色框中定义的打字
(如下图所示),我正在寻找指导。
如有错误,请指正
(1) 但我收集到的是 (T-Var)
返回给定变量 x
的类型。 Haskell 中的什么构造返回 type
?我知道在 prelude
中它是 :t x
,但我正在寻找一个在 main = do
下工作的。
(2) 如果我要定义一个函数 type_of
,很可能我需要定义预期类型和返回类型,例如,type_of (Var x)::type1 -> type2
type1
应该是通用的,type2
必须是存储变量类型信息的任何对象类型。为此,我不知道如何定义 type1
和 type2
。
(3) 对于 (T-APP) 和 (T-ABS),我假设我分别对抽象字符串 Lambda
和应用程序 Lambda Lambda
应用替换。简化形式的类型是返回的类型。这是正确的吗?
提前致谢...
最佳答案
从简单类型的 lambda 演算中得到的关键是,类型在 lambda 绑定(bind)器本身上进行注释,每个 lambda 项都有一个类型。 Pierce 提供的打字规则是如何机械地类型检查表达式的类型是否正确。 类型推断是他在本书后面讨论的一个主题,即从非类型化表达式中恢复类型。
此外,Pierce 在这个示例中没有给出的是几个基本类型 (Bool
, Int
) ,这在实现算法时很有帮助,所以我们'只需将它们附加到我们的定义中即可。
t = x
| λ x : T . t
| t t
| <num>
| true
| false
T = T -> T
| TInt
| TBool
如果我们将其翻译成 Haskell,我们会得到:
type Sym = String
data Expr
= Var Sym
| Lam Sym Type Expr
| App Expr Expr
| Lit Ground
deriving (Show, Eq, Ord)
data Ground = LInt Int
| LBool Bool
deriving (Show, Eq, Ord)
data Type = TInt
| TBool
| TArr Type Type
deriving (Eq, Read, Show)
贯穿方程的 Γ
是针对类型环境的,我们可以在Haskell中将其表示为简单的列表结构。
type Env = [(Sym, Type)]
空环境Ø
就是[]
。当 PIL 斯写下Γ, x : T ⊢ ...
时,他的意思是使用绑定(bind)到类型T
的x
定义扩展的环境。在 Haskell 中,我们会像这样实现它:
extend :: Env -> (Sym, Type) -> Env
extend env xt = xt : env
为了从 TAPL 编写检查器,我们实现了一个小错误 monad 堆栈。
data TypeError = Err String deriving Show
instance Error TypeError where
noMsg = Err ""
type Check a = ErrorT TypeError Identity a
check :: Env -> Expr -> Check Type
check _ (Lit LInt{}) = return TInt
check _ (Lit LBool{}) = return TBool
-- x : T ∈ Γ
-- ----------
-- Γ ⊦ x : T
check env (Var x) = case (lookup x env) of
Just e -> return e
Nothing -> throwError $ Err "Not in Scope"
-- Γ, x : T ⊦ e : T'
-- --------------------
-- Γ ⊦ λ x . e : T → T'
check env (Lam x t e) = do
rhs <- (check (extend env (x,t)) e)
return (TArr t rhs)
-- Γ ⊦ e1 : T → T' Γ ⊦ e2 : T
-- ----------------------------
-- Γ ⊦ e1 e2 : T'
check env (App e1 e2) = do
t1 <- check env e1
t2 <- check env e2
case t1 of
(TArr t1a t1r) | t1a == t2 -> return t1r
(TArr t1a _) -> throwError $ Err "Type mismatch"
ty -> throwError $ Err "Trying to apply non-function"
runCheck :: Check a -> Either TypeError a
runCheck = runIdentity . runErrorT
checkExpr :: Expr -> Either TypeError Type
checkExpr x = runCheck $ check [] x
当我们在表达式上调用 checkExpr
时,我们要么返回表达式的有效类型,要么返回一个 TypeError
指示函数出了什么问题。
例如,如果我们有术语:
(λx : Int -> Int . x) (λy : Int. y) 3
App (App (Lam "x" (TArr TInt TInt) (Var "x")) (Lam "y" TInt (Var "y"))) (Lit (LInt 3))
我们希望类型检查器验证其输出类型为 TInt
。
但是对于这样的术语来说失败了:
(λx : Int -> Int . x) 3
App (Lam "x" (TArr TInt TInt) (Var "x")) (Lit (LInt 3))
因为 TInt
不等于 (TInt -> TInt)
。
这就是 STLC 类型检查的全部内容。
关于Haskell 用于 Lambda 演算、类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20404220/
(图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
我是一名优秀的程序员,十分优秀!