Does a Haskell type system consider a numerical value as a function?

After playing with haskell a bit, I came across this function:

Prelude Data.Maclaurin> :t ((+) . ($) . (+)) ((+) . ($) . (+)) :: (Num a) => a -> (a -> a) -> a -> a 

(Data.Maclaurin is exported by the vector space of the package.) Thus, it takes Num, a function, another Num, and ultimately returns Num. What magic does the next job?

 Prelude Data.Maclaurin> ((+) . ($) . (+)) 1 2 3 6 

2 is obviously not a function (a-> a) or am I missing something?

+6
types haskell numeric typeclass
source share
2 answers

Data.NumInstances module of the same package defines a Num for functions that return numbers:

 instance Num b => Num (a->b) where (+) = liftA2 (+) (*) = liftA2 (*) fromInteger = pure . fromInteger ... 

In Haskell, an integer literal of type 2 is shared, so it can represent a number for any Num instance:

 Prelude> :t 2 2 :: (Num t) => t 

To convert it to the actual type number required in the specific context, fromInteger from the Num class is called.

Since the auxiliary module mentioned above defines a Num instance for functions, 2 can now be converted to a function with the fromInteger method specified there. Therefore, ghci calls fromInteger 2 to get the required function as the second construction parameter in the question. Then the whole expression evaluates to 6 .

+16
source share

You have good reason to be confused. Using the Data.NumInstances module in the GHC (which is loaded by Data.Maclaurin ), you can force Num to be used for a constant function.

 Prelude Data.NumInstances> :t (2 :: (Num a) => a -> a) (2 :: (Num a) => a -> a) :: (Num a) => a -> a Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 0 2 Prelude Data.NumInstances> (2 :: (Num a) => a -> a) 1000 2 

Evaluation of the expression is essentially

 ((+) . ($) . (+)) 1 2 3 = ((+) . ($) . (1+)) 2 3 = ((+) (1+)) 2 3 -- (+) is defined for functions that return a Num = ((+) (1+) (\_ -> 2)) 3 = ((+2) . (1+)) 3 = 6 
+1
source share

All Articles