[英]Haskell, lambda calculus for Evaluation
(图1)
简单类型的lambda演算的一部分(图1),它在Haskell中实现,如下所示。
evaluate expression = do
case expression of
(Application (Lambda x ltype term) value) | isValue value = True -> substitute term x value
(Application value e2) | isValue value = True -> let e22 = evaluate e2 in Application value e22
(Application e1 e2) -> let e11 = evaluate e1 in Application e11 e2
但是,这不适用于这些测试用例,
1) print (evaluate (Application (Var "x") (Var "y")))
2) print (evaluate (Application (Constant 3) (Var "y"))
“(常数3)是一个值”
但是,对于第一个测试用例,我知道这是因为(Var "x")
因为e1
是终端所以它不能转换。 这是否意味着我应该添加一个Stuck
案例? 但是如果可能的话,我想返回一个表明转换成功的输出。
先感谢您...
如果你正在实现你的lambda演算AST
data Exp = Var String
| Constant Int
| App Exp Exp
| Lam String Exp
然后解释器evaluate :: Exp -> Out
可以产生许多值,有些是输入效果不佳的结果。 例如
evaluate (Lam "f" (Lam "x" (App (Var "f") (Var "x")))
-- type like (a -> b) -> a -> b
evaluate (Var "x")
-- open term, evaluation gets stuck
evaluate (App (Lam "x" (Constant 4)) (Constant 3))
-- term results in a constant
我们需要在返回类型中表示所有这些类型。 一种典型的方法是使用类似的通用类型
data Out
= Stuck
| I Int
| F (Out -> Out)
这又强调了卡住案件的必要性。 如果我们检查evaluate
的App
分支
evaluate (App e1 e2) = case evaluate e1 of
Stuck -> Stuck
I i -> Stuck
F f -> f (evaluate e2)
显示Stuck
案件如何升至顶部并且可能来自键入不良的术语。
有许多方法可以在Haskell中编写一个良好类型的简单类型的lambda演算类型。 我非常喜欢高阶抽象语法最终编码 。 它非常对称。
class STLC rep where
lam :: (rep a -> rep b) -> rep (a -> b)
app :: rep (a -> b) -> (rep a -> rep b)
int :: Int -> rep Int
newtype Interpreter a = Reify { interpret :: a } -- just the identity monad
instance STLC Interpreter where
lam f = Reify $ interpret . f . Reify
app f a = Reify $ interpret f $ interpret a
int = Reify
在这个公式中,根本不可能编写一种类型的STLC rep => rep a
,它不是很好的类型且永不粘连。 interpret
的类型也表明了这一点
interpret :: Interpreter a -> a
看不到Out
类型。
但是, substitute
如何起作用(即haskell中substitute
函数的实现是什么)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.