在Haskell中读一个lambda术语

时间:2015-03-23 20:16:11

标签: haskell lambda lambda-calculus

我的lambda术语定义如下:

type Symb = String

infixl 2 :@

data Expr = Var Symb
        | Expr :@ Expr
        | Lam Symb Expr
        deriving Eq

我需要为ReadShow类型类编写实例,这样lambda-term将在Haskell语法中显示为有效的术语。

我'已完成Show,看起来很简单。但我在Read班上遇到了一些麻烦。

我写了这样的东西作为测试

instance Read Expr where
   readsPrec _ = myReadsExpr

myReadsExpr :: ReadS Expr
myReadsExpr s = [(Lam "x" (Var "x"), b) | (a, b) <- lex s]

但在ghci我有

*Fp06> myReadsExpr "\\x -> x"
[(\x -> x,"x -> x")]

没关系,但是当我做的时候

*Fp06> read "\\x -> x" :: Expr

我得到例外

*Fp06> read "\\x -> x" :: Expr
*** Exception: Prelude.read: no parse

你能告诉我,我做错了什么?先感谢您!

UPD:你能帮我进一步实施吗?我需要在我的类型中解析它们,因此术语\\x y z -> x (y z)将在Lam "x" (Lam "y" Lam "z" (Var "x" :@ (Var "y" :@ Var "z")))中解析

我不明白,如何处理括号,以及如何解析该术语。现在我以这种方式实现了Read

myReadsExpr :: ReadS Expr
myReadsExpr s = 
[(Lam var expr, thunk2) |   ("\\", rest)    <- lex s,
                            (var, thunk)    <- lex rest,
                            ("->", thunk1)  <- lex thunk,
                            (expr, thunk2)  <- myReadsExpr thunk1]
++
[(Var sym, t)           |   (sym, t)        <- reads s]
++
[(Var x :@ Var y, t1)   |   (x, t)          <- lex s,
                            (y, t1)         <- lex t] 

1 个答案:

答案 0 :(得分:3)

如果来自read的元组中的第二个元素是非空的,则

readsPrec会抛出错误。在解析之后,第二个元素代表String的其余部分。