Haskell:Num如何举行?

时间:2018-01-02 06:45:53

标签: haskell types typeclass

在以下示例中:

> let sum::Num a=> a->a->a; sum a b = a +b
> let partialSum = sum 1
> partialSum 2.0
3.0

在步骤let partialSum = sum 1中,似乎a被解释为Integer,但我认为Haskell将其延迟,直到它可以找出类型(以及因此使用哪个类型类实例),直到构建整个表达式为止。 我们可以解释这个,因为最终的结果是Fractional(3.0)

但此时let partialSum = sum 1 GHCI必须将1保留在记忆中,我想知道它是什么呢?

2 个答案:

答案 0 :(得分:7)

答案可分为两个部分:

  • 类型类约束被详细描述为记录,并且它们会在需要时自动传递。

  • 数字文字n已翻译为fromInteger n

所以

sum :: Num a => a -> a -> a
sum a b = a + b

会变成:

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

,其中

data RecordNum a = RecordNum
    { plus :: a -> a -> a
    ; mult :: a -> a -> a
    (...)
    ; fromInteger :: Integer -> a
    }

然后

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

变为

partialSum' :: RecordNum a -> a -> a
partialSum' dict = sum' dict (fromInteger dict 1)

答案 1 :(得分:7)

  

但此时let partialSum = sum 1 GHCi必须在内存中保持1

当然可以,但请记住,Haskell数字文字已经过载。在这种情况下,1会被存储为fromInteger (1 :: Integer) :: Num a => apartialSum坚持这一点,直到知道a应该是什么。 GHCi只保留1 Integer