为什么不能在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
不会失去准确性。