I am trying to write numerical methods for calculating the integral
module NumericalMethods(
trapezoidal_method
) where
type Func = Double -> Double
type Interval = [Double]
type N = Integer
trapezoidal_method:: Func -> Interval -> N -> Double
trapezoidal_method f interval n = h*((f (head interval) f $ tail interval)/2 sum_fxs)
where
h :: Double
h = (tail interval - head interval) / fromIntegral n
sum_fxs = sum fxs
fxs = map f [head interval h * fromIntegral x | x <- [1..n-1]]
I get this error:
• Couldn't match expected type ‘Double -> Double’ with actual type ‘Double’
• Possible cause: ‘f’ is applied to too many arguments
In the first argument of ‘( )’, namely ‘f (head interval)’
In the first argument of ‘($)’, namely ‘f (head interval) f’
In the first argument of ‘(/)’, namely ‘(f (head interval) f $ tail interval)’
|
10 | trapezoidal_method f interval n = h*((f (head interval) f $ tail interval)/2 sum_fxs)
| ^^^^^^^^^^^^^^^^^
CodePudding user response:
One issue is your use of $
in f (head interval) f $ tail interval
.
The $
operator has the lowest precedence of almost everything, so it will be interpreted as (f (head interval) f) $ (tail interval)
. It is trying to figure out what you mean with f (head interval) f
.
You probably just want to use parentheses: f (head interval) f (tail interval)
.
A second issue is your use of lists for intervals. I think tuples would be more suitable:
type Interval = (Double, Double)
Then you can use fst
and snd
instead of the erroneous head
and tail
:
trapezoidal_method:: Func -> Interval -> N -> Double
trapezoidal_method f interval n = h*((f (fst interval) f (snd interval))/2 sum_fxs)
where
h :: Double
h = (snd interval - fst interval) / fromIntegral n
sum_fxs = sum fxs
fxs = map f [fst interval h * fromIntegral x | x <- [1..n-1]]