为什么不能在haskell中添加整数和浮点数

为什么不能在haskell中添加整数和浮点数,haskell,Haskell,为什么这不起作用:- (length [1,2,3,4]) + 3.2 虽然这样做有效:- 2+3.3 我知道在第一种情况下结果是Int+Float,但在第二种情况下结果也不一样,或者Haskell会自动推断第二种情况下的类型为:-Num+Num,而在第一种情况下它不会这样做吗?在第一种情况下,如您所述,length[1,2,3,4]是一个显式的Int,不能隐式转换为Float或任何分数的实例。而在第二种情况下,没有显式类型,因此Haskell可以推断好的类型是分数的一个实例。您可以在中看到

为什么这不起作用:-

(length [1,2,3,4]) + 3.2
虽然这样做有效:-

2+3.3

我知道在第一种情况下结果是Int+Float,但在第二种情况下结果也不一样,或者Haskell会自动推断第二种情况下的类型为:-Num+Num,而在第一种情况下它不会这样做吗?

在第一种情况下,如您所述,
length[1,2,3,4]
是一个显式的
Int
,不能隐式转换为
Float
或任何
分数的
实例。而在第二种情况下,没有显式类型,因此Haskell可以推断好的类型是
分数的一个实例。您可以在中看到编译器如何处理数值文本


解决方法:
(fromIntegral$length[1,2,3,4])+3.2
整数文本,例如第二个示例中的
2
,被编译器隐式视为
fromInteger 2
。这意味着它们被转换为任何必需的数字类型,因为
fromInteger
的返回类型是多态的;在这种情况下,使用
Float
。但是,
length[1,2,3,4]
的类型是
Int
,而不是文本,因此需要显式转换其值。

Haskell从不为您进行隐式类型转换<代码>+
仅适用于同一类型的两个数字,并将该类型作为结果提供给您。
+
的任何其他用法都是错误的,正如您在
(长度[1,2,3,4])+3.2
示例中看到的那样

但是,数字文本在Haskell中重载
2
可以是任何数字类型,
3.3
可以是任何分数类型。因此,当Haskell看到表达式
2+3.3
时,它可以尝试找到一种同时是“数值”和“分数”的类型,并将这两个数字都视为该类型,这样加法就能起作用

更准确地说,
+
的类型是
numa=>a->a->a
<代码>2本身属于类型
Num a=>a
3.3
本身属于类型
分数a=>a
。将这三种类型放在一起,表达式
2+3.3
中的两个数字都可以被赋予类型
分数a=>a
,因为所有
分数
类型也都是
Num
类型,这也满足了
+
的类型。(如果在GHCi中键入此表达式,
a
将以
Double
的形式填写,因为GHC必须将类型默认为某个值才能对其求值)

在表达式
(长度[1,2,3,4])+3.2
中,
3.2
仍然重载(并且在隔离状态下将具有类型
分数a=>a
)。但是
length[1,2,3,4]
具有类型
Int
。由于一面是固定的具体类型,满足
+
类型的唯一方法是在另一面的
a
中填入
Int
,但这违反了
分数约束;
3.2
不可能成为
Int
。所以这个表达式的类型不是很好


但是,任何
Integral
类型(其中
Int
是一种类型)都可以通过应用
fromIntegral
转换为任何
Num
类型(这实际上就是像
2
这样的整数文本可以被视为任何数字类型的方式)。因此
(from integral$length[1,2,3,4])+3.2
将起作用。

Haskell不支持隐式转换。为什么?嗯,它们使类型系统复杂化,但也有潜在的不安全性。无法保证将
Int
转换为
Float
不会失去准确性。