Haskell type errors? - haskell

I'm really new to Haskell, and it's giving me quite a time. I was trying to write a basic function similar to 'linspace' in Matlab but the compiler seems to reject the idea that 'floor' produces an Integral type. My code:
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = floor ((y - x) / dx)
nums = [0..n]
y' = (x + (fromIntegral n) * dx)
Which produces an error in ghci:
maths.hs:8:21: error:
* No instance for (Integral Double) arising from a use of `floor'
* In the expression: floor ((y - x) / dx)
In an equation for `n': n = floor ((y - x) / dx)
In an equation for `linspace':
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = floor ((y - x) / dx)
nums = [0 .. n]
y' = (x + (fromIntegral n) * dx)
maths.hs:10:28: error:
* No instance for (Integral Double)
arising from a use of `fromIntegral'
* In the first argument of `(*)', namely `(fromIntegral n)'
In the second argument of `(+)', namely `(fromIntegral n) * dx'
In the expression: (x + (fromIntegral n) * dx)
Failed, modules loaded: none.

You have bound the result of linspace to be a [Double], due to the type annotation. Therefore, [x + i * dx | i <- nums] must produce such a list of Doubles. x and dx are bound to be Double as they are parameters passed to the function, which are all declared as Double. But what about i? It stems from nums; to have i be a Double, nums must be a [Double].
Nums is defined as
nums = [0..n]
Okay, nums is a list alright. But a list of what? That depends on n; let's take a look!
n = floor ((y - x) / dx)
floor takes, in a nutshell, your Double and produces an Integral. Therefore, nums is a list of integrals. This is the error you're getting: there is no instance of Integral for Double; there is no way for the types to work out nicely.
To fix those errors, you have to make n a Double:
n = fromIntegral $ floor ((y - x) / dx)
As such, your definition of y' must be changed as well:
y' = x + n * dx
In a nutshell
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + i * dx | i <- nums]
| otherwise = ([x + i * dx | i <- nums] ++ [y])
where
n = fromIntegral $ floor ((y - x) / dx)
nums = [0.. n]
y' = (x + n * dx)

This version compiles:
linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
| y' == y = [x + (fromIntegral i) * dx | i <- nums]
| otherwise = ([x + (fromIntegral i) * dx | i <- nums] ++ [y])
where
n = toInteger $ floor ((y - x) / dx)
nums = [0..n]
y' = (x + (fromIntegral n) * dx)
What are the changes?
As #Alec commented, while floor is logically an integer, it's type is not. You need to use toInteger.
Following that, you need to use fromIntegral when multiplying i and `dex.

Related

Haskell Int to Float division

I want to find, if there is a same divisor between y,x and z,y following:
myFunc [x,y,z] = if y `div` x == z `div` y then True else False
But here I get True even if the divisor is not the same, let´s assume we have
x = 32
y = 64
z = 129
I suppose the problem is with div, which only makes int division. Is there any int to float divison in haskell that I could use to solve it?
div is floor division. It returns floor of a/b. Change your function to:
myFunc [x,y,z] = (y `foo` x) == (z `foo` y) where foo a b = (fromIntegral a) / (fromIntegral b)

Instance for function with several classes

I want to realize power function for my custom data type. I mean power (^) which has following signature:
(^) :: (Num a, Integral b) => a -> b -> a
And I mean that my data type MyData should be instance of Num, so I could write
x :: MyData
...
y = x ^ b
where b is some Integral. It's very easy when we need function of one class like
(+), (-), (*) :: (Num a) => a -> a -> a
We just write
instance Num MyData where
(*) x y = someFunc x y
But I have no idea how to define it taking into account that there is also Integral b. That syntax should be like
instance (Integral b) => Num MyData b where
(^) x y = someFunc x y
But I've tried a hundred of such variations and nothing works. Hours of googling also didn't help.
You don't have to do anything to define (^) for your data type; if your type has a Num instance, you get x ^ b for free, because (^) is defined for any type with a Num instance. (It basically just calls * a lot.)
Note that (^) is not a member of Num or Integral; it's just a standalone function whose type is constrained by both classes.
From https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Real.html#%5E
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
x0 is your MyData value; the only thing (^) ever does with x0 (by virtue of it being passed as the x argument to f or g) is to multiply it by itself, so technically (^) will work as long as you have defined (*) in your Num instance.

Haskell Recursion ( No instance for (RealFrac Int) arising from a use of ‘round’)

modPow :: Int -> Int -> Int -> Int
-- Pre: 1 <= m <= sqrt(maxint)
modPow x y n
|even y = (((x^halfy) `mod` n)^2) `mod` n
|otherwise = (x `mod` n)*(x ^ (y-1) `mod` n) `mod` n
where halfy = round (y/2)
REPORT ON TERMINAL:
Recursion.hs:39:19:
No instance for (RealFrac Int) arising from a use of ‘round’
In the expression: round (y / 2)
In an equation for ‘halfy’: halfy = round (y / 2)
In an equation for ‘modPow’:
modPow x y n
| even y = (((x ^ halfy) `mod` n) ^ 2) `mod` n
| otherwise = (x `mod` n) * (x ^ (y - 1) `mod` n) `mod` n
where
halfy = round (y / 2)
Recursion.hs:39:27:
No instance for (Fractional Int) arising from a use of ‘/’
In the first argument of ‘round’, namely ‘(y / 2)’
In the expression: round (y / 2)
In an equation for ‘halfy’: halfy = round (y / 2)
In halfy = round (y/2), you have y :: Int. However, the (/) operator is defined in the Fractional typeclass (which Int is not an instance of; think about which Int could represent e.g. 3/2).
However, there are also the integer division operators div and quot which will give you rounded, Int results. So just replace that definition of halfy with
halfy = y `quot` 2
This will recover your inteded behaviour of halfy since, forgetting about the typing issues for a moment, the fractional part of y/2 is always going to be either 0 or 0.5, and round rounds both towards 0:
Prelude> round (1/2) :: Int
0
Prelude> round (-1/2) :: Int
0
Prelude> 1 `quot` 2 :: Int
0
Prelude> (-1) `quot` 2 :: Int
0
Prelude> (-1) `div` 2 :: Int -- This doesn't recover the same behaviour for negative y!
-1

Recursive Haskell; Newton's Method: Why Doesn't This Converge?

I've been trying to learn Haskell by building short programs. I'm somewhat new to the functional programming world but have already done a good amount of reading.
I have a relatively short recursive function in Haskell for using Newton's method to find roots of a function up to the precision allowed by floating point numbers:
newtonsMethod :: (Ord a, Num a, Fractional a) => (a -> a) -> (a -> a) -> a -> a
newtonsMethod f f' x
| f x < epsilon = x
| otherwise =
newtonsMethod f f' (x - (f x / f' x))
where
epsilon = last . map (subtract 1) . takeWhile (/= 1)
. map (+ 1) . iterate (/2) $ 1
When I interpret in GHCi and plug in newtonsMethod (\ x -> cos x + 0.2) (\ x -> -1 * sin x) (-1), I get -1.8797716370899549, which is the first iteration of Newton's method for the values called.
My first question is straightforward: why does it only recurse once? Please also let me know if you see any potential improvements to the way this code is structured or flagrant mistakes.
My second question, a little more involved, is this: is there some clean way to test parent calls of this function, see if it's failing to converge, and bail out accordingly?
Thanks in advance for any answer you can give!
It runs only once because -1.8... is less than epsilon, a strictly positive quantity. You want to check to see if the absolute value of the difference is within tolerance.
One way to get convergence diagnostics for this kind of code is to generate your results as a lazy list, not unlike how you found epsilon using iterate. That means that you can get your final result by traversing the list, but you can also see it in the context of the results that lead up to it.
I couldn't help re-writing it co-recursively and to use automatic differentiation. Of course one should really use the AD package: http://hackage.haskell.org/package/ad. Then you don't have to calculate the derivative yourself and you can see the method converge.
data Dual = Dual Double Double
deriving (Eq, Ord, Show)
constD :: Double -> Dual
constD x = Dual x 0
idD :: Double -> Dual
idD x = Dual x 1.0
instance Num Dual where
fromInteger n = constD $ fromInteger n
(Dual x x') + (Dual y y') = Dual (x + y) (x' + y')
(Dual x x') * (Dual y y') = Dual (x * y) (x * y' + y * x')
negate (Dual x x') = Dual (negate x) (negate x')
signum _ = undefined
abs _ = undefined
instance Fractional Dual where
fromRational p = constD $ fromRational p
recip (Dual x x') = Dual (1.0 / x) (-x' / (x * x))
instance Floating Dual where
pi = constD pi
exp (Dual x x') = Dual (exp x) (x' * exp x)
log (Dual x x') = Dual (log x) (x' / x)
sqrt (Dual x x') = Dual (sqrt x) (x' / (2 * sqrt x))
sin (Dual x x') = Dual (sin x) (x' * cos x)
cos (Dual x x') = Dual (cos x) (x' * (- sin x))
sinh (Dual x x') = Dual (sinh x) (x' * cosh x)
cosh (Dual x x') = Dual (cosh x) (x' * sinh x)
asin (Dual x x') = Dual (asin x) (x' / sqrt (1 - x*x))
acos (Dual x x') = Dual (acos x) (x' / (-sqrt (1 - x*x)))
atan (Dual x x') = Dual (atan x) (x' / (1 + x*x))
asinh (Dual x x') = Dual (asinh x) (x' / sqrt (1 + x*x))
acosh (Dual x x') = Dual (acosh x) (x' / (sqrt (x*x - 1)))
atanh (Dual x x') = Dual (atanh x) (x' / (1 - x*x))
newtonsMethod' :: (Dual -> Dual) -> Double -> [Double]
newtonsMethod' f x = zs
where
zs = x : map g zs
g y = y - a / b
where
Dual a b = f $ idD y
epsilon :: (Eq a, Fractional a) => a
epsilon = last . map (subtract 1) . takeWhile (/= 1)
. map (+ 1) . iterate (/2) $ 1
This gives the following
*Main> take 10 $ newtonsMethod' (\x -> cos x + 0.2) (-1)
[-1.0,
-1.8797716370899549,
-1.770515242616871,
-1.7721539749707398,
-1.7721542475852199,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274,
-1.7721542475852274]

Haskell implementation of the law of cosines

I am trying to implement the law of cosines function, and here is my code:
cosC :: [a] -> a
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where x = head(tail(tail(sides)))
y = head(tail(sides))
z = head(sides)
But I get two errors:
No instance for (Fractional a)
arising from a use of `/'
In the expression: (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
In an equation for `cosC':
cosC sides
| length sides < 3 = 0
| otherwise = (x ^ 2 + y ^ 2 - z ^ 2) / (2 * x * y)
where
x = head (tail (tail (sides)))
y = head (tail (sides))
z = head (sides)
and
No instance for (Num a)
arising from the literal `2'
In the first argument of `(*)', namely `2'
In the first argument of `(*)', namely `2 * x'
In the second argument of `(/)', namely `(2 * x * y)'
Edit: I have fixed the sign typo in the law of cosines above. Thanks to Daniel Fischer for pointing that out.
You're trying to calculate numerical results out of general types a, that can't possibly work. (It's like trying to build a bridge not just for general road-vehicles but for general things, e.g. spaceships, skyscrapers, paper clips and neutron stars). Just add the Floating constraint to a:
cosC :: Floating a => [a] -> a
and you can perform any of the arithmetic operations you need for such a calculation. (Fractional is actually enough for this function, but you won't be able to calculate the arccos of the result then).
Unrelated to your problem, note that there's a much better way to decompose lists in Haskell:
cosC (x:y:z:_) = (x^2 + y^2 - z^2) / (2*x*y)
cosC _ = 0
is equivalent to your definition. Why are you taking the arguments as a list anyway? That's quite a Lisp-ish thing to do, in Haskell I'd prefer
cosC :: Floating a => a -> a -> a -> a
cosC x y z = (x^2 + y^2 - z^2) / (2*x*y)
cosC :: Fractional a => [a] -> a
And this is how you can find out (in ghci):
*Main> let fun [x, y, z] = (x * x + y * y + z * z) / (2 * x * y)
*Main> :type fun
fun :: Fractional a => [a] -> a

Resources