简体   繁体   中英

Haskell: How is Num held?

In the following example:

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

In step let partialSum = sum 1 it would appear that a is interpreted as Integer but I suppose Haskell delays this until it can figure out the type (and consequently which typeclass instance to use) until the whole expression is built. We can interpret this because the ultimate result is Fractional (3.0)

But at this point let partialSum = sum 1 GHCI has to hold 1 in memory, I was wondering what does it hold it as?

The answer can be broken down in two components:

  • Typeclass constraints get elaborated as records and they're automatically passed around whenever needed.

  • A numeric literal n is translated to fromInteger n

So

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

would become:

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

where

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

and then

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

becomes

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

But at this point let partialSum = sum 1 GHCi has to hold 1 in memory

Sure, but remember that Haskell number literals are overloaded. In this case, 1 gets stored as fromInteger (1 :: Integer) :: Num a => a . partialSum holds onto this until it knows what a should be. GHCi holds onto only 1 the Integer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM