The error now iCouldn't match expected type ‘Double’
with actual type ‘Double -> Double -> Double -> Double’ , Probable cause: ‘(+)’ is applied to too few arguments
In the expression: cubicQ ^ 3 + r ^^ 2
In an equation for ‘cubicDisc’: cubicDisc q r = cubicQ ^ 3 + r ^^ 2
cubicR :: Double -> Double -> Double -> Double -> Double
cubicR a b c d = (9*a*b*c-27*a^^2*d-2*b^^3)/(54*a^^3)
cubicQ :: Double -> Double -> Double -> Double
cubicQ a b c = (3*a*c-b^^2)/(9*a^^2)
cubicDisc :: Double -> Double -> Double
cubicDisc q r = cubicQ^3 + r^^2
cubicS :: Double -> Double -> Double
cubicS q r = (r + sqrt(q^^3+r^^2))**(1/3)
cubicT :: Double -> Double -> Double
cubicT q r = (r - sqrt(q^^3+r^^2))**(1/3)
cubicRealSolutions :: Double -> Double -> Double -> Double -> [Double]
cubicRealSolutions a b c d = if cubicDisc > 0 || root == 0
then [rootOne,rootTwo,rootThree]
else []
where
rootOne= (cubicS + cubicT) - b/(3*a)
rootTwo = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
rootThree = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
Syntactically, your program does not make sense, that's what the compiler is complaining about. First, the if statement is just floating around; its not in the same scope as cubicRealSolutions. I would recommend revising and reading through some Haskell documentation on let, if, and function syntax . For now, if I were you I would clean up the code as follows:
cubicRealSolutions :: Double -> Double -> Double -> Double -> [Double]
cubicRealSolutions a b c d = if cubicDisc > 0 || root == 0
then [rootOne,rootTwo,rootThree]
else []
where
root = 0
rootOne= (cubicS + cubicT) - b/(3*a)
rootTwo = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
rootThree = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
cubicDisc = 18*a*b*c*d - 4*(b^3)*d + (b^2)*(c^2) - 4*a*c^3 - 27*(a^2)*(d^2)
cubicS = 0.1
cubicT = 0.2
However, there are still major issues with this code and it will not compile because root,cubicDisc, cubicS, cubicT are not defined. Also, you never use the parameters c or d which I find odd, as you probably want to use them. Finally, if statements must evaluate to the same type, hence the else evaluates to an empty list instead of a string. Even my revision is not "good" style. There are too many statements in the where clause. If this happens its best to break the function down into smaller parts to avoid run-on where clauses. I've used ... to indicate what you need to define for the compiler.
References: LYAH
PS: Personally, I find where syntax to be easier to understand than let but that is up to personal style choices. Although, let is a bit more flexible than where.
EDIT: I have defined root, cubicS, and cubicT with placeholder values to illustrate that they must evaluate to a Double.
Related
I have the following code which uses Newton's method to approximate the square root of some number. The problems is that when I run it, I get an error..What is wrong and how can I fix it?
newtonRootSequence :: Double -> [Double]
newtonRootSequence d = newtonSequenceGenerator d 1
newtonSequenceGenerator :: Double -> Double -> [Double]
newtonSequenceGenerator d xn = nxplus1 : newtonSequenceGenerator d nxplus1
where nxplus1 = (xn + d / xn) / 2
newtonRoot:: Double -> Double -> Double
newtonRoot d epsilon = head ([xs !! index | index <- [1..((length xs) - 1)], (xs !! index) - (xs !! index - 1) <= epsilon]
where xs = newtonRootSequence d
Error:
<interactive>:2:1: error:
* No instance for (Show (Double -> Double))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of an interactive GHCi command: print it
Running it should be like the following:
$newtonRoot 35
In Haskell all function are curryfied, so, your function
newtonRoot:: Double -> Double -> Double
the are "hidden parenthesis":
newtonRoot:: Double -> (Double -> Double)
if you provide one argument newtonRoot 35 you have
(newtonRoot 35) :: Double -> Double
and a function f :: Double -> Double is not instance of Show type class
You need to finally provide the last argument to your function value:
(newtonRoot 35 2) :: Double
Double can me shown
newtonRoot takes two arguments, a d and an epsilon. You didn't supply an epsilon. Try
> newtonRoot 35 0.1
instead.
There are other errors, too, but this should get you started down the debugging path.
I have the following code which uses Newton's method to approximate the square root of some number. The problems is that when I run it, I get an error..What is wrong and how can I fix it?
newtonRootSequence :: Double -> [Double]
newtonRootSequence d = newtonSequenceGenerator d 1
newtonSequenceGenerator :: Double -> Double -> [Double]
newtonSequenceGenerator d xn = nxplus1 : newtonSequenceGenerator d nxplus1
where nxplus1 = (xn + d / xn) / 2
newtonRoot:: Double -> Double -> Double
newtonRoot d epsilon = head ([xs !! index | index <- [1..((length xs) - 1)], (xs !! index) - (xs !! index - 1) <= epsilon]
where xs = newtonRootSequence d
Error:
<interactive>:2:1: error:
* No instance for (Show (Double -> Double))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of an interactive GHCi command: print it
Running it should be like the following:
$newtonRoot 35
In Haskell all function are curryfied, so, your function
newtonRoot:: Double -> Double -> Double
the are "hidden parenthesis":
newtonRoot:: Double -> (Double -> Double)
if you provide one argument newtonRoot 35 you have
(newtonRoot 35) :: Double -> Double
and a function f :: Double -> Double is not instance of Show type class
You need to finally provide the last argument to your function value:
(newtonRoot 35 2) :: Double
Double can me shown
newtonRoot takes two arguments, a d and an epsilon. You didn't supply an epsilon. Try
> newtonRoot 35 0.1
instead.
There are other errors, too, but this should get you started down the debugging path.
I'm new to Haskell. I got this question from my assignment. It ask me to make this code work:
area_of_triangle :: Float
-> Float
-> Float
-> Maybe Float
I know how to do this without Maybe; it's like:
area_of_triangle :: Float -> Float -> Float -> Float
area_of_triangle a b c = sqrt(s*(s-a)*(s-b)*(s-c))
where
s = (a+b+c)/2
I guess the requirement would be if area_of_triangle=0.0, return Nothing (because such the triangle doesn't exist). But I don't know how to write this.
Three lengths can only form a triangle if the sum of each pair of lengths is greater than the other length. In the cases where that is not true, return Nothing. Otherwise, you can return Just a, where a is the length you calculate with your original formula.
area_of_triangle :: Float -> Float -> Float -> Float
area_of_triangle a b c = sqrt(s*(s-a)*(s-b)*(s-c))
where
s = (a+b+c)/2
area :: Float -> Float -> Float -> Maybe Float
area a b c
| ??? = Nothing
| ??? = Nothing
| ??? = Nothing
| otherwise = Just (???)
I leave it as an exercise to figure out what Boolean expressions replace the first three ???s, and what to replace the last ??? with.
Figured it out eventually
area_of_triangle :: Float -> Float -> Float -> Maybe Float
area_of_triangle x y z
| x+y>=z && x+z>=y && y+z>=x = Just (sqrt(s*(s-x)*(s-x)*(s-x)))
| otherwise = Nothing
where
s=(x+y+z)/2
I would break this up into three functions:
-- | Takes three numbers and indicates
-- whether they can be the lengths of
-- the sides of a (non-degenerate)
-- triangle.
triangleInequality :: (Num a, Ord a)
=> a -> a -> a -> Bool
triangleInequality x y z
| ??? &&
??? &&
??? = ???
| otherwise = ???
uncheckedArea :: RealFloat a
=> a -> a -> a -> a
uncheckedArea x y z = ???
area :: RealFloat a
=> a -> a -> a -> Maybe a
area x y z
| ??? = Just ???
| otherwise = Nothing
According to this draft article, you can improve the numerical stability of your calculation as follows:
area a' b' c'
| c - (a - b) <= 0 = Nothing
| otherwise = Just $ 0.25 * sqrt ((a+(b+c)) * (c-(a-b)) * (c+(a-b)) * (a+(b-c)))
where
[c, b, a] = sort [a',b',c']
However, I don't know that GHC can be trusted to calculate that exactly as written, so some additional care may be required.
Note that you may be better off accepting 0-area "triangles" for some purposes.
I've written some code that's meant to integrate a function numerically using the trapezoidal rule. It works, but the answer it produces has a wrong sign. Why might that be?
The code is:
integration :: (Double -> Double) -> Double -> Double -> Double
integration f a b = h * (f a + f b + partial_sum)
where
h = (b - a) / 1000
most_parts = map f (points (1000-1) h)
partial_sum = sum most_parts
points :: Double -> Double -> [Double]
points x1 x2
| x1 <= 0 = []
| otherwise = (x1*x2) : points (x1-1) x2
Trapezoidal rule
The code is probably inelegant, but I'm only a student of Haskell and would like to deal with the current problem first and coding style matters after that.
Note: This answer is written in literate Haskell. Save it with .lhs as extension and load it in GHCi to test the solution.
Finding the culprit
First of all, let's take a look at integration. In its current form, it contains only summation of function values f x. Even though the factors aren't correct at the moment, the overall approach is fine: you evaluate f at the grid points. However, we can use the following function to verify that there's something wrong:
ghci> integration (\x -> if x >= 10 then 1 else (-1)) 10 15
-4.985
Wait a second. x isn't even negative in [10,15]. This suggests that you use the wrong grid points.
Grid points revisited
Even though you've linked the article, let's have a look at an exemplary use of the trapezoidal rule (public domain, original file by Oleg Alexandrov):
Although this doesn't use a uniform grid, let's suppose that the 6 grid points are equidistant with grid distance h = (b - a) / 5. What are the x coordinates of those points?
x_0 = a + 0 * h (== a)
x_1 = a + 1 * h
x_2 = a + 2 * h
x_3 = a + 3 * h
x_4 = a + 4 * h
x_5 = a + 5 * h (== b)
If we use set a = 10 and b = 15 (and therefore h = 1), we should end up with [10, 11, 12, 13, 14, 15]. Let's check your points. In this case, you would use points 5 1 and end up with [5,4,3,2,1].
And there's the error. points doesn't respect the boundary. We can easily fix this by using pointsWithOffset:
> points :: Double -> Double -> [Double]
> points x1 x2
> | x1 <= 0 = []
> | otherwise = (x1*x2) : points (x1-1) x2
>
> pointsWithOffset :: Double -> Double -> Double -> [Double]
> pointsWithOffset x1 x2 offset = map (+offset) (points x1 x2)
That way, we can still use your current points definition to generate grid points from x1 to 0 (almost). If we use integration with pointsWithOffset, we end up with
integration :: (Double -> Double) -> Double -> Double -> Double
integration f a b = h * (f a + f b + partial_sum)
where
h = (b - a) / 1000
most_parts = map f (pointsWithOffset (1000-1) h a)
partial_sum = sum most_parts
Tying up loose ends
However, this doesn't take into account that you use all inner points twice in the trapezoid rule. If we add the factors, we end up with
> integration :: (Double -> Double) -> Double -> Double -> Double
> integration f a b =
> h / 2 * (f a + f b + 2 * partial_sum)
> -- ^^^ ^^^
> where
> h = (b - a) / 1000
> most_parts = map f (pointsWithOffset (1000-1) h a)
> partial_sum = sum most_parts
Which yields the correct value for our test function above.
Exercise
Your current version only supports 1000 grid points. Add an Int argument so that one can change the number of grid points:
integration :: Int -> (Double -> Double) -> Double -> Double -> Double
integration n f a b = -- ...
Furthermore, try to write points in different ways, for example go from a to b, use takeWhile and iterate, or even a list comprehension.
Yes it indeed was the points plus you had some factors wrong (the inner points are multiplied by 2) - this is the fixed version of your code:
integration :: (Double -> Double) -> Double -> Double -> Double
integration f a b = h * (f a + f b + innerSum) / 2
where
h = (b - a) / 1000
innerPts = map ((2*) . f . (a+)) (points (1000-1) h)
innerSum = sum innerPts
points :: Double -> Double -> [Double]
points i x
| i <= 0 = []
| otherwise = (i*x) : points (i-1) x
which gives sensible approximations (to 1000 points):
λ> integration (const 2) 1 2
2.0
λ> integration id 1 2
1.5
λ> integration (\x -> x*x) 1 2
2.3333334999999975
λ> 7/3
2.3333333333333335
Hi I can't figure this out myself and i also couldn't find an example online
I'm trying to use a maybe or a guard and the examples i found have just two variables,
when i edit or follow the examples with more then two i get an error heres what i am trying to do
--maybe example
Fun :: Double -> Double -> Double -> Maybe Double
Fun a b c
| a >= -1.0 || a <= 1.0 || b >= -1.0 || b <=1.0 || c /=0 || c >= -1.0 = Nothing
| otherwise = Just max( ((c^ (-c)) + (a^(-c)-1.0) ^ (a+ (-1.0/a))) 0.0)
error with gchi
The function `Just' is applied to two arguments,
but its type `a0 -> Maybe a0' has only one
while hlint gives
No suggestions
trying to use a guard instead i get a different error
--guard example
Fun :: Double -> Double -> Double -> Maybe Double
Fun a b c
| a >= -1.0 || a <= 1.0 || b >= -1.0 || b <=1.0 || c /=0 || c >= -1.0 = error "Value out of range "
| otherwise = max( ((c^ (-c)) + (a^(-c)-1.0) ^ (a+ (-1.0/a))) 0.0)
and heres ghc and hlints errors
test.hs:10:1:
Invalid type signature: Fun :: Double
-> Double -> Double -> Maybe Double
Should be of form <variable> :: <type>
$ hlint test.hs
Error message:
Left-hand side of type signature is not a variable: Fun
Code:
Fun :: Double -> Double -> Double -> Maybe Double
> Fun a b c
You must write functions with a lower-case letter. This means writing this:
fun :: Double -> Double -> Double -> Maybe Double
fun a b c ...
Functions can never start with upper-case letters, since upper-case identifiers are reserved for modules (Data.List for example) and type constructors and data constructors (like Int or Maybe or Just) and some other things.
You also have an issue with the application of the Just constructor. If you write this:
Just max(something)
... it means the same thing as:
Just max something
i.e. you are giving Just two arguments. You need to fix this by adjusting your parens:
Just (max something)
Syntax errors, mostly:
f :: Double -> Double -> Double -> Maybe Double
f a b c
| a >= -1
|| a <= 1
|| b >= -1
|| b <= 1
|| c /= 0
|| c >= -1
= Nothing
| otherwise
= Just $ max ((c ** (-c)) + (a ** (-c)-1) ** (a+ (-1/a))) 0
Note the use of the more generally-typed exponention operator, (**), and $ to avoid parens in the Just wrapper over max.