给出以下数据类型E:
data E = IntLit Int
| BoolLit Bool
| Plus E E
| Minus E E
| Multiplies E E
| Exponentiate E E
| Equals E E
deriving (Eq, Show)
这是我的代码,上面的数据正在运行所有这些。
data E = IntLit Int
| BoolLit Bool
| Plus E E
| Minus E E
| Multiplies E E
| Divides E E
| Equals E E
| log2Sim E E
deriving (Eq, Show)
eval :: E -> E
eval c@(IntLit i) = c
eval c@(BoolLit b) = c
eval (Plus a b) = plus (eval a) (eval b)
eval (Minus a b) = minus (eval a) (eval b)
eval (Multiplies a b) = multiplies (eval a) (eval b)
eval (Divides a b) = divides (eval a) (eval b)
eval (Equals a b) = equals (eval a) (eval b)
log2Sim :: E -> E
log2sim = case (eval x) of
IntLit i -> IntLit (logBase 2 i)
x1 -> "type error: can't take the log of a non-IntLit-valued expresstio" ++ show x1
plus (IntLit i) (IntLit j) = IntLit $ i + j
plus _ _ = error "Type error in addition"
minus (IntLit i) (IntLit j) = IntLit $ i - j
minus _ _ = error "Type error in subtraction"
multiplies (IntLit i) (IntLit j) = IntLit $ i * j
multiplies _ _ = error "Type error in multiplication"
divides (IntLit i) (IntLit j) = IntLit $ i `div` j
divides _ _ = error "Type error in division"
equals (IntLit i) (IntLit j) = BoolLit $ i == j
equals (BoolLit a) (BoolLit b) = BoolLit $ a == b
equals _ _ = error "Type error in equals"
当我编译它时,有一些错误。 这是什么错误?
A3.hs:56:7:
Couldn't match expected type `E' against inferred type `[Char]'
In the expression:
"type error: can't take the lof of a non-IntLit-valued expression: "
++
show x1
In a case alternative:
x1
-> "type error: can't take the lof of a non-IntLit-valued expression: "
++
show x1
In the expression:
case (eval x) of
IntLit i -> IntLit (logBase 2 i)
x1
-> "type error: can't take the lof of a non-IntLit-valued expression: "
++
show x1
答案 0 :(得分:4)
您的代码中存在许多问题:
data E = ... | log2Sim E E
不正确。你也可能只想要一个E
,因此例如data E = ... | Log E
可以解决这两个问题。您声明了log2Sim
但定义了log2sim
(请注意大小写的差异)。您还忘记在定义中的x
左侧写入参数=
。通过编写
log2Sim x = ...
字符串不是E
类型的有效表达式。您可能希望通过调用error
将错误字符串转换为E
来遵循代码其余部分中的模式。因此:
x1 -> error $ "type error: can't take the log of a non-IntLit-valued expresstio" ++ show x1
logBase
对Floating
点数进行操作,Int
不是一个。有几种方法可以解决这个问题,但是这里和那里之间的最短距离是转换为Double
并返回。例如:
IntLit i -> IntLit . floor . logBase 2 . fromIntegral $ i
这足以使您的代码编译,但可能存在其他问题。