--|符号表达--递归数据类型和单体的练习--2016年功能编程课程。--托马斯·哈格伦{-这从一个骨架开始,定义被填充在讲座期间。-}模块符号表达式,其中导入数据。列表(联合)导入数据。也许(来自Just)进口管制。单车(ap,liftM)--|带变量的算术表达式的Haskell数据类型data Expr=整数|变量名称--新建|添加Expr Expr|多重Expr Expr|Div Expr Expr--新推导(等式)type Name=字符串ex1=数字2ex2=相加(数字2)ex3=倍数(加(数字1)(数字2))(数字3)ex4=相加(数字1)(倍数(数字2)(数字3))ex5=分区x(倍数(数字2)y)ex6=倍数(数字2)xx=变量“x”y=变量“y”--------------------------------------------------------------------------------实例Show Expr其中show=showExprshowExpr::Expr->字符串showExpr(添加e1 e2)=showExpr e1++“+”++showExpr e2showExpr e=显示因子eshowFactor::Expr->StringshowFactor(Mul e1 e2)=显示因子e1++“*”++显示因子e2showFactor(分区e1 e2)=showFactore 1++“/”++showDivisor e2showFactor e=showDivisor eshowDivisor::Expr->字符串showDivisor(Num n)=显示nshowDivisor(Var x)=xshowDivisor e=“(”++showExpr e++“)”----------------------------------------------------------------------------------|正在收集变量vars::表达式->[名称]vars(数字n)=[]变量(变量x)=[x]vars(添加a b)=vars a`union`vars bvars(Mul a b)=vars a`union`vars bvars(Div a b)=vars a`union`vars b----------------------------------------------------------------------------------|评估符号表达式eval::[(名称,整数)]->表达式->整数eval env(Num n)=neval env(Var x)=fromJust(查找x env)eval env(添加a b)=eval enva+eval env-beval env(Mul a b)=评价环境a*评价环境beval env(Div a b)=eval env`Div`eval env-b----------------------------------------------------------------------------------|符号区分差异::表达式->名称->表达式diff(数字n)x=数字0diff(Var y)x=如果y==x,则数字1,否则数字0diff(添加a b)x=添加(diff a x)(diff b x)diff(多a b)x=加(多a x)b)(多a(多b x))--*智能施工人员添加(数字0)b=b添加a(数字0)=aadd(数字a)(数字b)=数字(a+b)添加一个b|a==b=mul(数字2)aadd a b=添加a bmul(数字0)b=数字0mula(数字0)=数字0mul(数字1)b=bmul a(数字1)=amul(数字a)(数字b)=数字(a*b)mula b=mula b----------------------------------------------------------------------------------|应用表达式计算器--evalA::Expr->整数evalA(数量n)=纯nevalA(加e1 e2)=(+)评估A(Mul e1 e2)=(*)----------------------------------------------------------------------------------*避免被零除evalD(Num n)=纯nevalD(加e1 e2)=(+)评估D(Mul e1 e2)=(*)evalD(分区e1 e2)=执行<-evalD e1b<-评估e2安全分区1 a bsafeDiv1::整数->整数->可能是整数safeDiv1 x 0=无safeDiv1 x y=仅(x`div`y)----------------------------------------------------------------------------------*使环境含蓄{-evalE(数字)=评估E(Var x)=evalE(添加a b)=评估E(Mula b)=--}----------------------------------------------------------------------------------*用于评估的单子--|用于环境和避免故障的monad数据评估a=E([(名称,整数)]->可能a)运行E(E f)=f实例Functor Eval,其中fmap=提升M实例应用评估,其中纯=返回(<*>)=ap实例Monad Eval,其中--return::a->Eval评估return x=E(\env->仅x)--(>>=)::评估a->(a->评估b)->评估bE m>>=f=E(\env->do x<-m env;运行E(f x)env)divByZero=E(\env->无)lookupVar x=E(查找x)safeDiv x 0=按零分配safeDiv x y=返回(x`div`y)evalM(数量n)=纯nevalM(Var x)=查找变量xevalM(加a b)=(+)评估M(Mula b)=(*)评估M a评估M bevalM(分区a b)=do x<-evalM ay<-评估M bsafeDiv x y(安全分区x y)