Home > Software engineering >  how to use type correctly in a function?
how to use type correctly in a function?

Time:12-05

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]]
  • Related