Reputation: 40319
In the following code, the where value=
clause returns a partially applied function.
How can I ensure it gets fully applied?
------------------------------
future_value :: Float -> Float -> Float -> Float
future_value present interest periods =
(present * (( 1 + interest) ** periods))
------------------------------
-- Given an initial amount
-- Given a yearly fee, as well as a yearly interest...
-- Calculates return over a number of years, given a yearly fee.
return_over_time :: Float -> Float -> Float -> Float -> Float
return_over_time present interest num_years fee =
if num_years == 1 then (future_value present interest 1.0) - fee
else future_value value
where value = return_over_time present interest (num_years - 1) fee
Upvotes: 2
Views: 155
Reputation: 54584
If it makes no sense that a function is ever partially applied, you can change it to take a tuple:
future_value :: (Float, Float, Float) -> Float
future_value (present, interest, periods) =
(present * (( 1 + interest) ** periods))
Using this definition error messages get much more "localized", the compiler will complain about passing a (Float, Float)
instead of (Float,Float,Float)
or so, and not about something fancy like a missing Show
instance for (->)
. However this is just a little trick for beginners, as for most functions currying makes a lot of sense, and sooner or later you get used to it and learn to fix errors resulting from missing arguments quickly.
Upvotes: 1
Reputation: 68152
The issue isn't with value
but with future_value
. future_value
takes three arguments but you only give it one (value
), so future_value value
has the type Float -> Float - > Float
. value
, on the other hand, is just a Float
because return_over_time
is fully applied in the where
clause.
You can make sure future_value
is fully applied by passing in two more floats for interest
and periods
.
Incidentally, is there any particular reason you are using Float
instead of Double
?
Upvotes: 4