Haskell 哈斯克尔:Num是如何举行的?

Haskell 哈斯克尔:Num是如何举行的?,haskell,types,typeclass,Haskell,Types,Typeclass,在以下示例中: > let sum::Num a=> a->a->a; sum a b = a +b > let partialSum = sum 1 > partialSum 2.0 3.0 在步骤中,让partialSum=sum 1看起来a被解释为整数,但我想Haskell会延迟这一过程,直到它能够计算出类型(以及要使用的typeclass实例),直到构建整个表达式。 我们可以解释这一点,因为最终结果是分数(3.0) 但是在这一点上,让partialS

在以下示例中:

> let sum::Num a=> a->a->a; sum a b = a +b
> let partialSum = sum 1
> partialSum 2.0
3.0
在步骤
中,让partialSum=sum 1
看起来a被解释为整数,但我想Haskell会延迟这一过程,直到它能够计算出类型(以及要使用的typeclass实例),直到构建整个表达式。 我们可以解释这一点,因为最终结果是分数(3.0)


但是在这一点上,让partialSum=sum 1GHCI必须将
1
保存在内存中,我想知道它是作为什么保存的

答案可分为两部分:

  • Typeclass约束作为记录进行详细说明,并在需要时自动传递

  • 数值文本
    n
    被转换为

所以

将成为:

sum' :: RecordNum a -> a -> a -> a
sum' dict a b = (plus dict) a b
在哪里

然后

partialSum :: Num a => a -> a
partialSum = sum 1
变成

partialSum' :: RecordNum a -> a -> a
partialSum' dict = sum' dict (fromInteger dict 1)
但此时,让partialSum=sum 1GHCi必须在内存中保存1


当然可以,但请记住Haskell数字文本是重载的。在本例中,
1
存储为
fromInteger(1::Integer)::Num a=>a
partialSum
会一直保持这个状态,直到它知道
a
应该是什么。GHCi只保留
1
整数

我想知道fromIntegral是否是唯一的方法,因此只能以上述方式使用整数。例如,这不起作用:```let f=1::Float let d=2::Double let sum Num::a=>a->a->a;求和AB=a+b让partialSum=sum f partialSum d``导致error@Ngm您可以通过添加类型注释自然地确保文本是特定类型的,尽管除非将其强制为WNHF,否则无法保证该类型的实际文本将存储在该点上。还值得注意的是,像
1#
1.0#
这样的非固定文本是存在的(它们更接近于其他语言的值类型,但Haskell初学者使用的频率较低)。这难道不是整数文本从整数n转换为
partialSum=sum 2.5
的解释略有不同。
partialSum :: Num a => a -> a
partialSum = sum 1
partialSum' :: RecordNum a -> a -> a
partialSum' dict = sum' dict (fromInteger dict 1)