Haskell如何确定表达式是否简单?
我正在编写一个函数来确定表达式是否简单。在我的例子中,一个简单的表达式是一个没有可用函数调用的表达式。我有以下Exp类型: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 (
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