Haskell,lambda演算用于评估

时间:2013-12-09 13:46:14

标签: haskell types lambda lambda-calculus evaluate

Figure 1

(图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案例?但是如果可能的话,我想返回一个表明转换成功的输出。

提前谢谢你......

2 个答案:

答案 0 :(得分:4)

如果您正在将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)

再次强调需要卡住的情况。如果我们检查App

evaluate分支
evaluate (App e1 e2) = case evaluate e1 of
  Stuck -> Stuck
  I i   -> Stuck
  F f   -> f (evaluate e2)

显示Stuck个案件如何上升到顶部,并且可能来自输入不良的字词。


在Haskell中有很多方法可以编写类型很好的简单类型的lambda演算类型。我非常喜欢Higher-Order Abstract Syntax Final Encoding。它非常对称。

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 - 即刻输入。

答案 1 :(得分:0)

但是,substitute如何工作(即haskell中substitute函数的实现是什么)。