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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With