Haskell如何确定表达式是否简单?

Haskell如何确定表达式是否简单?,haskell,functional-programming,Haskell,Functional Programming,我正在编写一个函数来确定表达式是否简单。在我的例子中,一个简单的表达式是一个没有可用函数调用的表达式。我有以下Exp类型: data Exp = IntExp Integer | VarExp String | LamExp String Exp | IfExp Exp Exp Exp | OpExp String Exp Exp | AppExp Exp Exp deriving (

我正在编写一个函数来确定表达式是否简单。在我的例子中,一个简单的表达式是一个没有可用函数调用的表达式。我有以下Exp类型:



data Exp = IntExp Integer
         | VarExp String
         | LamExp String Exp
         | IfExp Exp Exp Exp
         | OpExp String Exp Exp
         | AppExp Exp Exp
         deriving (Eq)
我确信我的职能部门的类型签名如下:

isSimple :: Exp -> Bool
以下是一些测试用例:

Main Lib> isSimple (AppExp (VarExp "f") (IntExp 10))
False
*Main Lib> isSimple (OpExp "+" (IntExp 10) (VarExp "v"))
True
*Main Lib> isSimple (OpExp "+" (IntExp 10) (AppExp (VarExp "f") (VarExp "v")))
False
正如您所看到的,第一个和第三个表达式具有函数的应用程序表达式,因此并不简单。但我甚至不知道如何开始运作,以便作出决定。任何帮助都将不胜感激。非常感谢。 编辑: 对不起,我应该添加我当前的进度。我有一个直截了当的方法,实际上似乎太简单了:


isSimple (AppExp e1 e2) = False
isSimple (IntExp e1) = True
isSimple (VarExp s1) = True

isSimple (IfExp e1 e2 e3) = (isSimple e1) && (isSimple e2) && (isSimple e3)
isSimple (OpExp s1 e1 e2) = (isSimple e1) && (isSimple e2)


但是lambda表达式也会有点棘手。

TL;当(且仅当)lambda表达式的主体是简单的时,它是简单的


从某种意义上说,lambda表达式只是运算符表达式的一个特例,除非操作的语义编码在语法中。例如,您可以想象将
OpExp
拆分为多个特定于操作员的情况:

data Exp = IntExp Integer
     | VarExp String
     | LamExp String Exp
     | IfExp Exp Exp Exp
     | AddExp Exp Exp  -- x + y
     | MulExp Exp Exp  -- x * y
     | AndExpr Exp Exp -- x && y
     | ...
     | AppExp Exp Exp
其中一个lambda表达式,如
λx。x+3
变为

OpExp "λ" (VarExp "x") (OpExp "+" (VarExp "x") (IntExp 3))
(就像
+
*
的两个参数必须是
IntExp
s或计算为
IntExp
s的表达式一样,
λ
要求其第一个参数是
VarExp
。这些是语法本身无法捕捉到的语义约束。)

在这种情况下,
isSimple
对于
OpExp
的定义仍然成立:只要绑定变量(第一个参数)和主体(第二个参数)都很简单,表达式就很简单

因此,对其进行定义似乎是完全合理的

isSimple (LamExp _ e) = isSimple e

继续对
Exp
类型进行递归。使用模式匹配,处理每个构造函数。添加了我的进度,但似乎过于简单。我觉得你的尝试还可以。我不确定您想如何处理lambda表达式。您能否提供一些使用lambdas的示例,以便我们了解您打算获得的结果?理想情况下,提供一个lambda,我们应该返回true,另一个为false。当您认为表达式对于lambda表达式来说是简单的时,还不太清楚。你能解释一下你想要这个函数做什么吗?谢谢你的解释。我自己也在考虑一种类似的方法,我来编辑我的问题并发表评论,只是想看看你的完美解释。
isSimple (LamExp _ e) = isSimple e