2011-09-27 50 views
4

我正在研究可以计算表达式中使用的运算符数的函数。我的代码如下:计算表达式中的运算符数 - 无法推论实例

data Expr = Lit Int | 
    Expr :+: Expr | 
    Expr :-: Expr 

size :: Expr -> Int 
size (Lit n)  = 0 
size (e1 :+: e2) = 1 + (size e1) + (size e2) 
size (e1 :-: e2) = 1 + (size e1) + (size e2) 

但是当我尝试使用Hugs98我碰到下面的错误来执行该代码:

Main> size 2+3 
ERROR - Cannot infer instance 
*** Instance : Num Expr 
*** Expression : size 2 + 3 

有人能告诉我什么,我做错了什么?我真的没有想法,我自己。

+1

从我+1没有一个SO帐户,并要求这样一个很好格式化,措词和标签的问题。 –

+1

您在2 + 3周围缺少括号。此外,您必须将Num实例添加到您的Expr类型。 – fuz

+3

只是为了好玩:http://ideone.com/WsAk5 –

回答

5

2+3不是一个有效的表达式。对于您的类型,使用数据构造函数Lit创建原始值,有效运算符为:+::-:。所以你真正需要的是Lit 2 :+: Lit 3。因此,尝试

size (Lit 2 :+: Lit 3) 
+1

我看到了,谢谢你的建议。我的印象是':'可以作为中缀构造函数。我真的不希望任何人为我做功课,但是如何让功能大小以(2 + 3)为参数来做什么呢?我的Expr定义是错误的还是函数大小本身? – tvd

+3

@ user967306:这些没什么不对,'(2 + 3)'不是'Expr',它是一个整数(实际上'Num a => a'')。如果你想构建一个'Expr'树,你必须明确地使用这些构造函数(保存聪明的技巧,比如使'Expr'成为'Num'的实例,并定义'fromInteger = Lit'和'(+)=(:+: )',这可能不是有意做的,哪种可能在任何情况下都不明确 - 但请参阅拉蒙的评论)。 – delnan

0

你可以把它民实例:

instance Num Expr where 
    (+) = (:+:) 
    (-) = (:-:) 
    negate = (0 -) 
    fromInteger = Lit . fromInteger 
    (*) = error "not implemented" 
    abs = error "not implemented" 
    signum = error "not implemented" 

一旦到位,size (2+3)就可以了(注意括号)。