Function type mismatch - haskell

I have a function with function type :
newtonRootSequence' :: Double -> Double -> [Double]
and function definition:
newtonRootSequence' xn d = [(xn + (d * (1/xn))) div 2] ++ newtonRootSequence' ((xn + (d * (1/xn))) div 2) d
upon receiving two values xn and d it should calculate the results for the given function
[(xn + (d * (1/xn))) div 2]
But for some reason on launch the compilator is not accepting the function with an error:
Couldnt match expected type '(Integer->Integer->Integer->) ->Integer
->Double with actual type double the function (xn + (d * (1/xn))) div 2) is applied to two arguments
This error occurs to the part where I try to send the result of the equation into the recursive step
++ newtonRootSequence' ((xn + (d * (1/xn))) div 2) d

As already mentioned in the comments:
if you want to use div as an infix function, you have to enclose it in backticks
div is for integral division with truncation towards negative infinity, not for dividing Double
These two points are the cause for your error message.
To divide Doubles, use the / operator like you already did in your expression 1/xn.
With this your code should work. For clarity it could be transformed:
Extract the duplicated expression to compute the next xn in the sequence into a where clause. The expression can also be slightly simplified. Adding a single element in front of a list can simply be done with the cons operator (:):
newtonRootSequence' xn d = xn' : newtonRootSequence' xn' d
where xn' = (xn + (d / xn)) / 2
You could use iterate :: (a -> a) -> a -> [a] from the Prelude to separate the computation for a single step from the generation of the list of intermediate steps (note the flipped arguments):
sequenceStep :: Double -> Double -> Double
sequenceStep s xn = (xn + (s / xn)) / 2
newtonRootSequence' :: Double -> Double -> [Double]
newtonRootSequence' s x0 = iterate (sequenceStep s) x0

Related

Confusion about data types in Haskell

I have to write a simple pi approximation and I did and it works fine, but in the task it says to write a function with the header "pi_approx :: Int -> Double".
My code:
pi_approx x = sqrt (pi2_approx(x))
pi2_approx x =
if x/= 1
then (6 /(x*x)) + (pi2_approx(x-1))
else (6/(1*1))
However my function works fine without "pi_approx :: Int -> Double", but when i try to use this declaration I always get the type error:
pi_approx.hs:10:14: error:
Couldn't match expected type Double' with actual type Int'
In the expression: (+) (6 / (x * x)) (pi2_approx (x - 1))
In the expression:
if x /= 1 then
(+) (6 / (x * x)) (pi2_approx (x - 1))
else
(6 / (1 * 1))
In an equation for `pi2_approx':
pi2_approx x
= if x /= 1 then
(+) (6 / (x * x)) (pi2_approx (x - 1))
else
(6 / (1 * 1))
|
10 | then (+) (6 /(x*x)) (pi2_approx(x-1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I tried to use fromIntegral in various ways and if I run the function without declaration I checked the type of the solution, which is: "(Floating a, Eq a) => a"
As I understand Double should be an instance of Floating so I don´t understand why it wont compile.
I am very new at haskell and it seems I don´t understand the core concept of data types and constraints. I can´t seem to find any simple and good documentation/explanation on the topic though. Maybe someone here can help me understand based on this example :)
because x is an Int, hence x * x is also an Int, and you can not use an Int for (/) :: Floating a => a -> a -> a.
You need to convert this to a Double, for example with fromIntegral :: (Integral a, Num b) => a -> b:
pi2_approx :: Int -> Double
pi2_approx 1 = 6
pi2_approx x = 6 / fromIntegral (x*x) + pi2_approx (x-1)
For a large number of iterations, it gives a result close to π2:
Prelude> sqrt (pi2_approx 10000)
3.1414971639472147

Why am i getting this error (arising from a use of ‘print’) [duplicate]

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.

No instance for (Show (Double -> Double))

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.

Haskell numerical integration via Trapezoidal rule results in wrong sign

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

Haskell - Instance of Integral Float required for definition of unSum x = (y + y`mod`2 + 2) / 2 where y = x*(x+1) / 2

The Following code:
unSum :: Float -> Float
unSum x = (y + y`mod`2 + 2) / 2
where
y = x*(x+1) / 2
gives me this error when I try to load it into WinHugs 98:
Hugs> :load "D:\\kram\\unSumme2.hs"
ERROR file:.\unSumme2.hs:2 - Instance of Integral Float required for definition of unSumme2
What's the essence of this and how am I to do it? Anyway, I dont now if it serves my porpuse, I want to calculate the sum of the uneven numbers until x without recursivity.
It's because you're using mod. The definition of mod, from the Standard Prelude:
class (Real a, Enum a) => Integral a where
[...]
div, mod :: a -> a -> a
[...]
n `mod` d = r where (q,r) = divMod n d
In other words, it expects a to be of the numeric typeclass Integral, which includes only whole numbers.
If you want to stick with Floats, try using mod', from Data.Fixed, per this answer.
Alternatively, if you just want to do integer division, you could change your function's signature to
unSum :: Int -> Int
or similar.

Resources