Reputation: 21
I'm creating a program to compute the solution to a cubic equation in haskell. I'm new to functional languages and I'm having some difficulties. Here is my code:
cubicQ :: Float -> Float -> Float -> Float
cubicQ a b c = ((3 * a * c) - (b**2)) / (9 * (a**2)) --calculates Q
cubicR :: Float -> Float -> Float -> Float -> Float
cubicR a b c d = ((9 * a * b * c) - (27 * a**2 * d) - (2 * b**3)) / (54
* a**3)--calculates R
cubicS :: Float -> Float -> Float
cubicS r q = (r + (sqrt(q**3 + r**2))) ** (1/3)--calculates S
cubicT :: Float -> Float -> Float
cubicT q r = (r - (sqrt(q**3 + r**2))) ** (1/3)--calculates T
check :: Float -> Float -> Float
check q r = ((q**3)+(r**2)) --checks for real numbers
x1 :: Float -> Float -> Float -> Float -> Float
x1 s t a b = (s + t) - (b / (3 * a)) --calculates x1
cubicRealSolution :: Float -> Float -> Float -> Float -> Float
--defines function which takes input and solves
cubicRealSolution a b c d = if l < 0 then error "NaN" else (sol) --Check
for real numbers
where
q = cubicQ
r = cubicR
s = cubicS
t = cubicT
l = check
sol = x1
I get this error when compiling, * Couldn't match expected type Float'
with actual type Float -> Float -> Float -> Float -> Float'
* Probable cause: sol' is applied to too few arguments
I'm not sure where to go from here. I can get it to work if i remove all of the functions and instead just make my variables equal to the computations that thr functions do, but it's for a school assignment and so I have to have these functions defined.
Upvotes: 1
Views: 1472
Reputation: 476709
In your cubicRealSolution
, you write:
where q = cubicQ
(some other declarations as well, but these all suffer from the same problem).
The problem with this is that you now define a function q
with type q :: Float -> Float -> Float -> Float
. You thus do not make a function call, you simply declare q
a function.
You call the function with cubicQ a b c
(where a
, b
and c
are de identifiers defined in the head of the cubicRealSolution
, not to be confused with the cubicQ
function).
So a function that at least would typecheck could look like:
cubicRealSolution :: Float -> Float -> Float -> Float -> Float
cubicRealSolution a b c d = if l < 0 then error "NaN" else sol
where q = cubicQ a b c
r = cubicR a b c d
s = cubicS r q
t = cubicT q r
l = check q r
sol = x1 s t a b
Haskell thus does not look for identifiers with the same name, and then calls the function with this parameters. Such "retrieval by name" would, in my opionion, be very unsafe, since adding an extra parameter (or renaming one) could have all sorts of effects that are very hard to predict. In fact the name of the parameter usually does not matter much (with some noteworthy exceptions like writing parts in template Haskell).
If cubicQ
however aims to calculate the roots of a cubical polynomial, then it seems to return the wrong result. So there is still a semantical problem.
Upvotes: 2