Home > Enterprise >  How is a functions of multiple parameters to be interpreted?
How is a functions of multiple parameters to be interpreted?

Time:09-17

Given the following function

multThree :: (Num a) => a -> a -> a -> a  
multThree x y z = x * y * z  

and this description of it:

What really happens when we do multThree 3 5 9 or ((multThree 3) 5) 9? First, 3 is applied to multThree, because they're separated by a space. That creates a function that takes one parameter and returns a function. So then 5 is applied to that, which creates a function that will take a parameter and multiply it by 15. 9 is applied to that function and the result is 135 or something. Remember that this function's type could also be written as multThree :: (Num a) => a -> (a -> (a -> a)).

I interpret this as follows and want to be sure that this is correct:

((multThree 3) 5) 9 =
((3*y*z)5)9 =
(15*z)9 =
15*9
= 135

Is this the correct interpretation of multThree's functionality as described in this paragraph?

CodePudding user response:

You are close but you miss a crucial point. ((3*y*z)5)9 is not a valid expression. In particular, while multThree in multThree 9 is a function, 3*y*z (the thing you substituted multThree with) is no longer a function. (Note also that y and z are used without being defined). To fix the problem we will rewrite multThree as

multThree = (\x -> (\y -> (\z -> x * y * z)))
-- or dropping all the unnecessary brackets
multThree = \x -> \y -> \z -> x * y * z

Now you can substitute and all works out:

multThree 3 5 9
= (\x -> \y -> \z -> x * y * z) 3 5 9
= (\y -> \z -> 3 * y * z) 5 9
= (\z -> 3 * 5 * z) 9
= 3 * 5 * 9

This might also raise another question about the order of evaluation of the multiplication operator (*). In our case (*) is left associative:

Prelude> :info (*)
class Num a where
  ...
  (*) :: a -> a -> a
  ...
    -- Defined in `GHC.Num'
infixl 7 *

That is, your 3 * 5 * 9 actually is (3 * 5) * 9.

CodePudding user response:

You forgot the lambdas, otherwise your interpretation is correct:

((multThree 3) 5) 9 =
((\y z -> 3*y*z)5)9 =
(\z -> 15*z)9 =
15*9
= 135

In fact, multThree 3 is the function that expects y and z, and returns 3*y*z. We write that as \y z -> 3*y*z.

Similarly multThree 3 5 is the function that expects only z and returns 3*5*z. We write that as \z -> 3*5*z.

Finally multThree 3 5 9 is no longer a function, 3*5*9.

  • Related