Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Absolute Difference Using Function Compsition

I am trying to define a function to find the absolute difference of two numbers, such that both

absoluteDifference 2 5
absoluteDifference 5 2

return 3.

Here is my best effort so far:

absoluteDifference :: Num a => a -> a -> a
absoluteDifference = abs . (-)

In my head, this applies abs to the result of subtracting two numbers. However, this gives me the error

* Could not deduce (Num (a -> a)) arising from a use of `abs'
    (maybe you haven't applied a function to enough arguments?)
  from the context: Num a
    bound by the type signature for:
               absoluteDifference :: Num a => a -> a -> a
    at C:\Users\Adam\dev\daily-programmer\e311\e311.hs:3:1-42
* In the first argument of `(.)', namely `abs'
  In the expression: abs . (-)
  In an equation for `absoluteDifference':
      absoluteDifference = abs . (-)

Which I don't understand. I could trivially implement the function as

absoluteDifference a b = abs $ a - b

but I want to know how to compose the functions.

like image 378
Adam Hammes Avatar asked Feb 02 '26 15:02

Adam Hammes


1 Answers

The info for (.)

Prelude> :i (.)
(.) :: (b -> c) -> (a -> b) -> a -> c   -- Defined in ‘GHC.Base’

shows that it accepts functions with types a -> b

but (-) has the type

Prelude> :i (-)
class Num a where
  ...
  (-) :: a -> a -> a
  ...
    -- Defined in ‘GHC.Num’
infixl 6 -

so, it is possible to define another composition operator that accepts functions having the above type, and then they can be composed.

of' :: (a -> a) -> (a -> a -> a) -> a -> a -> a
of' f g a b = f (g a b)

abdiff = abs `of'` (-)

abdiff 1 10
9

note: as user @david-young points out correctly, of' can be more general by specifying the type as below:

of' :: (a -> b) -> (c -> d -> a) -> c -> d -> b
of' f g x y = f (g x y)
like image 91
Haleemur Ali Avatar answered Feb 05 '26 08:02

Haleemur Ali



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!