Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell's type system treats a numerical value as function?

After playing around with haskell a bit I stumbled over this function:

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

(Data.Maclaurin is exported by the package vector-space.) So it takes a Num, a function, another Num and ultimately returns a Num. What magic makes the following work?

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

2 is obviously not a function (a->a) or did I miss out on something?

like image 981
Long Avatar asked Mar 22 '10 23:03

Long


1 Answers

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

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

In Haskell an integer literal like 2 is generic so that it can represent a number for any instance of Num:

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

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

Since the helper module mentioned above defines an instance of Num for functions, 2 can now be converted to a function with the fromInteger method specified there. So ghci calls fromInteger 2 to get the function required as the second parameter of the construct in the question. The whole expression then happens to evaluate to 6.

like image 190
sth Avatar answered Sep 29 '22 07:09

sth