这是我的代码导致后面的错误:
import Prelude hiding (div)
data Expr = Expr Op Int Int deriving (Show)
data Op = Add | Sub | Mul | Div deriving (Show)
evaluate :: (Num a) => Expr -> a
evaluate (Expr Add a b) = a + b
--evaluate (Expr Sub a b) = sub a b
--evaluate (Expr Mul a b) = mul a b
--evaluate (Expr Div a b) = div a b
错误讯息:
exprs.hs:8:27: error:
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
evaluate :: forall a. Num a => Expr -> a
at exprs.hs:7:1-32
• In the expression: a + b
In an equation for ‘evaluate’: evaluate (Expr Add a b) = a + b
• Relevant bindings include
evaluate :: Expr -> a (bound at exprs.hs:8:1)
|
8 | evaluate (Expr Add a b) = a + b
| ^^^^^
Failed, 0 modules loaded.
但是,(+)函数的类型为(Num a) => a -> a -> a
,并且
我在函数evaluate
中匹配的模式有两个 Ints (a& b),这两个都是Num类型类的一部分。由于在&上调用(+)的结果b将是Int类型(来自Num类型类),这也是我声明我的evaluate
函数的输出类型,为什么GHCi会给我这个错误?
请注意,如果我将evaluate
的类型声明更改为
evaluate :: Expr -> Int
然后这个错误没有出现。
答案 0 :(得分:4)
evaluate :: (Num a) => Expr -> a
指出对于具有a
实例的任何类型Num
,evaluate
可以返回a
类型的值,给定Expr
1}}价值。但是根据Expr
的定义,您只能返回Int
,因此编译器会拒绝您的定义。
如果允许,你可以这样做:
evaluate (Expr Add 2 3) :: Double
你的定义无法满足。
如果允许Expr
通过表达式类型进行参数化,则可以使用您的定义:
data Expr a = Expr Op a a deriving (Show)
evaluate :: (Num a) => Expr a -> a
evaluate (Expr Add a b) = a + b
...