Function 为什么这被认为是类型不匹配(或错误)?
这是导致以下错误的代码:Function 为什么这被认为是类型不匹配(或错误)?,function,haskell,types,type-declaration,Function,Haskell,Types,Type Declaration,这是导致以下错误的代码: 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 --evalu
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
中匹配的模式有两个int(a和b),它们都是Num-typeclass的部分。由于在a&b上调用(+)的结果将是Int类型(来自Num typeclass),这也是我声明的evaluate
函数的输出类型,为什么GHCi会给我这个错误
注意,如果我将evaluate
的类型声明更改为
evaluate :: Expr -> Int
那么这个错误就不会出现了
evaluate :: (Num a) => Expr -> a
声明对于具有Num
实例的任何类型a
,evaluate
可以在给定Expr
值的情况下返回a
类型的值。但是,给定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
...
声明对于具有Num
实例的任何类型a
,evaluate
可以在给定Expr
值的情况下返回a
类型的值。但是,给定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
...
因此,具体来说,数据构造函数Expr Op Int只能有两个Int,这意味着函数定义中的(+)将始终返回一个Int,因此它与类型声明不匹配。。。我理解得对吗?@corecase-是的,没错-调用方可以选择类型
a
,而不是您的实现,因此您不能对其进行任何假设。@corecase该类型承诺,调用evaluate
的任何人都可以选择数字返回类型(例如aDouble
)。因此,evaluate
必须适应任何这样的选择,并且不能只涵盖Int
的情况。因此,具体来说,数据构造函数Expr Op Int Int只能有两个Int,这反过来意味着函数定义中的(+)将始终返回一个Int,因此它与类型声明不匹配。。。我理解得对吗?@corecase-是的,没错-调用方可以选择类型a
,而不是您的实现,因此您不能对其进行任何假设。@corecase该类型承诺,调用evaluate
的任何人都可以选择数字返回类型(例如aDouble
)。因此,evaluate
必须适应任何这样的选择,并且不能只涵盖Int
情况。