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 tomultThree
, 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 asmultThree :: (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
.