2017-10-16 74 views
1

我正在编写自己的haskell数据类型以解决整数求和操作,但我不知道如何编写语义。Haskell - 数据类型的算术运算

data Expr = Value Int 
    | Sum Expr Expr 

我试图做的事:

sum:: Expr -> Expr -> Int 
sum a b = b + a 
val:: Int -> Int 
val a = a 

我想写这样的:

Sum (Value 3) (Value 5) 

并获得8回报,任何想法?

+0

当你尝试时发生了什么? –

+1

'Sum(Value 3)(Value 5)'将* always *,根据定义,是一个不同的'Expr'类型值。你不能将它减少到8,因为'8'不是'Expr'的构造函数。 – chepner

回答

0

您需要为每个数据构造函数组合适当地定义sum

sum :: Expr -> Expr -> Int 
sum (Value x) (Value y) = x + y 
sum (Sum a b) (Sum c d) = sum a b + sum c d 
sum (Value x) (Sub a b) = x + sum a b 
sum (Sum a b) (Value y) = sum a b + y 

这可以简化;一种方法是使用帮助功能,首先将单个Expr减少为整数值。

value :: Expr -> Int 
value (Value x) = x 
value (Sum x y) = (value x) + (value y) 

sum :: Expr -> Expr -> Int 
sum x y = value x + value y  
4

通常,在这种情况,你写了一个“评估”或“解释” - 接受一个Expr和计算结果是值的单一功能:

eval :: Expr -> Int 

然后,你可以这样写:

> eval (Sum (Value 3) (Value 5)) 
8 
> 

Haskell的对于函数定义模式匹配使这很优雅:

eval (Value x) = ... 
eval (Sum e1 e2) = ...you'll need to use eval recursively here... 

因此,而不是写多个功能,一个为你Expr的每个组件,你写一个函数与一个基于模式的定义每个组件。

如果这是家庭作业,您可能想停下来尝试为自己弄清楚细节。如果不是,那么以下应该工作:

eval :: Expr -> Int 
eval (Value x) = x 
eval (Sum e1 e2) = eval e1 + eval e2 
+0

耶,你救了我。您的建议正常工作= D –