Haskell Float to Int to Float conversion Error - haskell

I want to convert the a Floating Point Number (0,123456) and round it with b (positive whole number).
I use the truncate function to round the Floating point number to a specific length "b"
This is the formula i came up with, however I get an error when compiling with the GHCI
The Function:
calcFloatingNum:: Double -> Int -> Int -> Float
calcFloatingNum a b = truncate ( a * 10^b) /10^b
The Error Code:
* No instance for (Integral Double)
arising from a use of `truncate'
* In the first argument of `(/)', namely `truncate (a * 10 ^ b)'
In the expression: truncate (a * 10 ^ b) / 10 ^ b
In an equation for `calcFloatingNum':
calcFloatingNum a b = truncate (a * 10 ^ b) / 10 ^ b
|
10 | calcFloatingNum a b = truncate ( a * 10^b) /10^b
And if I try anyway it states:
ghci> calcFloatingNum 0.2345 2
<interactive>:1:1: error:
Variable not in scope: calcFloatingNum :: t0 -> t1 -> t
ghci>
So the Signature might be the problem, however I can't seem to find the solution.
I tried converting the numbers with "fromInteger" and "toInteger", however it resulted in Error codes as well.

Besides the things I mentioned in my comments, this question is really an exercise in following the types and in particular the floating and integral types.
Let's start off with the type signatures of the functions that you are attempting to use. I'll use concrete types to keep things simple.
truncate :: Double -> Int
(^) :: Int -> Int -> Int
As you can see these functions produce integers, while you want floats. So whenever we use these function we need to use fromIntegral :: Int -> Double to convert the result back into Double:
calcFloatingNum:: Double -> Int -> Double
calcFloatingNum a b =
fromIntegral (truncate (a * fromIntegral (10 ^ b))) / fromIntegral (10 ^ b)

Related

Simple Haskell Average Function Gives Couldn't Match Type Error

All the other average questions I've seen are much more complicated than what I need. I am very new to Haskell and I'm currently working through The Craft of Functional Programming 2nd Edition.
In chapter 3 there is an exercise to write a simple function to average 3 integers. The function type signature is provided and I used it in my solution. I wrote:
averageThree :: Int -> Int -> Int -> Float
averageThree a b c = (a + b + c) / 3
I use ghci for compilation and when I try and load my file I get "Couldn't match expected type Float' with actual typeInt'". How do I fix this error?
The expression a + b + c will have type Int, and / is not even defined for Int. GHC will probably infer that 3 has type Float though. You have to explicitly cast the type in this situation, so you'd need to do
fromIntegral (a + b + c) / 3
The fromIntegral function takes an Integral a => a type like Int or Integer and converts it to a Num b => b type, which could also be Int or Integral, or Float, Double, Complex Double, and even custom numeric types.
You should use Fractional, to support Real division:
averageThree :: Fractional a => a -> a -> a -> a
averageThree a b c = (a + b + c) / 3
(/) :: Fractional a => a -> a -> a, which means / takes two fractional numbers of the same type and returns a fractional number of the same type. You are giving it an Int as an argument, which is not fractional, and asking for a Float as output. You must convert your Int to a Float before giving it to /. Use fromIntegral :: Int -> Float. fromIntegral (a + b + c) / 3. You could also leave off the type signature and ask ghci for the inferred type.

why is this snippet valid with an explicit value, but invalid as a function?

I'm trying to work a problem where I need to calculate the "small" divisors of an integer. I'm just bruteforcing through all numbers up to the square root of the given number, so to get the divisors of 10 I'd write:
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
This seems to work well. But as soon as I plug this in a function
f n=[k|k<-[1...floor(sqrt n)],rem n k<1]
And actually call this function, I do get an error
f 10
No instance for (Floating t0) arising from a use of `it'
The type variable `t0' is ambiguous
Note: there are several potential instances:
instance Floating Double -- Defined in `GHC.Float'
instance Floating Float -- Defined in `GHC.Float'
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
As far as I undrestand the actual print function that prints the result to the console is causing trouble, but I cannot find out what is wrong. It says the type is ambiguous, but the function can clearly only return a list of integers. Then again I checked the type, and it the (inferred) type of f is
f :: (Floating t, Integral t, RealFrac t) => t -> [t]
I can understand that fshould be able to accept any real numerical value, but can anyone explain why the return type should be anything else than Integral or int?
[k|k<-[1...floor(sqrt 10)],rem 10 k<1]
this works because the first 10 is not the same as the latter one - to see this, we need the type signature of your functions:
sqrt :: Floating a => a -> a
rem :: Integral a => a -> a -> a
so the first one means that it works for stuff that have a floating point representation - a.k.a. Float, Double ..., and the second one works for Int, Integer (bigint), Word8 (unsigned 8bit integers)...
so for the 10 in sqrt 10 the compiler says - ahh this is a floating point number, null problemo, and for the 10 in rem 10 k, ahh this is an integer like number, null problemo as well.
But when you bundle them up in a function - you are saying n has to be a floating point and an integral number, the compiler knows no such thing and - complains.
So what do we do to fix that (and a side note ranges in haskell are indicated by .. not ...!). So let us start by taking a concrete solution and generalize it.
f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
the neccessary part was converting the Int to a floating point number. But if you are putting that in a library all your users need to stick with using Int which is okay, but far from ideal - so how do we generalize (as promised)? We use GHCi to do that for us, using a lazy language we ourselves tend to be lazy as well.
We start by commenting out the type-signature
-- f :: Int -> [Int]
f n = [k|k <- [1..n'],rem n k < 1]
where n' = floor $ sqrt $ fromIntegral n
$> ghci MyLib.hs
....
MyLib > :type f
f :: Integral a => a -> [a]
then we can take this and put it into the library and if someone worked with Word8 or Integer that would work as well.
Another solution would be to use rem (floor n) k < 1 and have
f :: Floating a, Integral b => a -> [b]
as the type, but that would be kind of awkward.

Haskell, multiplying Int and Float within a function

Why is it that in ghci I can enter:
5.0 * (3 - 1)
> 10.0
But if I try and create a function in a .hs file and load it in:
test :: Float -> Int -> Int -> Float
test a b c = a * (b - c)
I am hit with an error? "Couldnt match expected type 'Float' against inferred type 'Int'?
And how can I write a function that takes in one floating point and 2 integer arguments and performs the above operation on them?
I am using ghci v6.12.1 if that makes a difference...
Numeric literals (i.e. just typing a number in Haskell code) are not some fixed type. They are polymorphic. They need to be evaluated in some context that requires them to have a concrete type.
So the expression 5.0 * (3 - 1) is not multiplying an Int by a Float. 5.0 has to be some Fractional type, 3 and 1 are each some Num type. 3 - 1 means that the 3 and the 1 both have to be the same Num type, but we still don't (yet) have any more constraints about which particular one it is; the result of the subtraction is the same type.
The * means both arguments have to be the same type, and the result will be the same type too. Since 5.0 is some Fractional type, the (3 - 1) must be too. We already knew that 3, 1, and (3 - 1) had to be some Num type but all Fractional types are also Num types, so this requirements are not in conflict.
The end result is that the whole expression 5.0 * (3 - 1) is some type that is Fractional, and the 5.0, 3, and 1 are all the same type. You can use the :t command in GHCi to see this:
Prelude> :t 5.0 * (3 - 1)
5.0 * (3 - 1) :: Fractional a => a
But to actually evaluate that expression, we need to do so for some concrete type. If we were evaluating this and passing it to some function that required Float, Double, or some other particular Fractional type then Haskell would pick that one. If we just evaluate the expression with no other context requiring it to be a particular type, Haskell has some defaulting rules to automatically choose one for you (if the defaulting rules don't apply it will instead give you a type error about ambiguous type variables).
Prelude> 5.0 * (3 - 1)
10.0
Prelude> :t it
it :: Double
Above I've evaluated 5.0 * (3 - 1), then asked for the type of the magic it variable which GHCi always binds to the last value it evaluated. This tells me that GHCi has defaulted my Fractional a => a type to just Double, in order to compute that the value of the expression was 10.0. In doing that evaluation, it only ever multipled (and subtracted) Doubles, it never multiplied a Double by an Int.
Now, that's what's going on when you attempt to multiple numeric literals that look like they might be of different types. But your test function isn't multiplying literals, it's multiplying variables of particular known types. In Haskell you can't multiply an Int by a Float because the * operator has type Num a => a -> a -> a - it takes two values of the same numeric type and gives you a result that is that type. You can multiply an Int by an Int to get an Int, or a Float by a Float to get a Float. You can't multiply an Int by a Float to get a ???.
Other languages support this sort of operation only by implicitly inserting calls to conversion functions under some circumstances. Haskell never implicitly converts between types, but it has the conversion functions. You just need to call them explicitly if you want them to be called. This would do the trick:
test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)
Try the following instead:
test :: Float -> Int -> Int -> Float
test a b c = a * fromIntegral (b - c)
Why does this work?
Since b and c are both Ints the expression (b - c) is also an Int.
The type signature of (*) is Num a => a -> a -> a.
Because a is of type Float Haskell updates the type signature of (a*) to Float -> Float.
However since (b - c) is an Int and not a Float Haskell would complain if you tried doing a * (b - c).
The type signature of fromIntegral is (Integral a, Num b) => a -> b.
Hence the type signature of fromIntegral (b - c) is Num b => b.
Since Float is an instance of typeclass Num you're allowed to do a * fromIntegral (b - c) because the type signature of (*) is Num a => a -> a -> a.
The result, from the type signature of test evaluates to Float.
Hope this helped.
You need to use fromIntegral on the integers before multiplying by the floats.
http://www.haskell.org/haskellwiki/Converting_numbers
In GHCI, the numbers aren't assumed to be floats or ints until you use them. (e.g: at run time). That works out better for REPL-style development.
In the compiler proper, there isn't any automatic coercion. It it sees the multiplication assumes that the two values must belong to a type-class that supports multiplication. e.g: multiplying ints , or multiplying floats. As you didn't use any other explicitly typed functions, it assumed ints. That assumption then differs with your (optional) type signature.
Your test function was more general, before you add a signature:
> let test a b c = a * (b - c)
> :t test
test :: Num a => a -> a -> a -> a
You could restrict it, but all types must be the same:
test :: Fractional a => a -> a -> a -> a -- some real types
test :: Integral a => a -> a -> a -> a -- all integer types
test :: Float -> Float -> Float -> Float
test :: Int -> Int -> Int -> Int
test :: Int -> Float -> Float -> Float --wrong
By the way, 2 isn't Int and 0.2 isn't Float, let ask gchi:
> :t 2
2 :: Num a => a
> :t 0.2
0.2 :: Fractional a => a

Unintuitive type signature in Haskell

I made this (what I thought to be) fairly straightforward code to calculate the third side of a triangle:
toRadians :: Int -> Double
toRadians d = let deg = mod d 360
in deg/180 * pi
lawOfCosines :: Int -> Int -> Int -> Double
lawOfCosines a b gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma))
However, when I tried to load it into GHCi, I got the following errors:
[1 of 1] Compiling Main ( law_of_cosines.hs, interpreted )
law_of_cosines.hs:3:18:
Couldn't match expected type `Double' with actual type `Int'
In the first argument of `(/)', namely `deg'
In the first argument of `(*)', namely `deg / 180'
In the expression: deg / 180 * pi
law_of_cosines.hs:6:26:
No instance for (Floating Int)
arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the expression: sqrt
In the expression:
sqrt $ a * a + b * b - 2 * a * b * (cos (toRadians gamma))
In an equation for `lawOfCosines':
lawOfCosines a b gamma
= sqrt $ a * a + b * b - 2 * a * b * (cos (toRadians gamma))
law_of_cosines.hs:6:57:
Couldn't match expected type `Int' with actual type `Double'
In the return type of a call of `toRadians'
In the first argument of `cos', namely `(toRadians gamma)'
In the second argument of `(*)', namely `(cos (toRadians gamma))'
It turns out the fix was to remove my type signatures, upon which it worked fine.
toRadians d = let deg = mod d 360
in deg/180 * pi
lawOfCosines a b gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma))
And when I query the type of toRadians and lawOfCosines:
*Main> :t toRadians
toRadians :: (Floating a, Integral a) => a -> a
*Main> :t lawOfCosines
lawOfCosines :: (Floating a, Integral a) => a -> a -> a -> a
*Main>
Can someone explain to me what's going on here? Why the "intuitive" type signatures I had written were in fact incorrect?
The problem is in toRadians: mod has the type Integral a => a -> a -> a, therefore, deg has the type Integral i => i (so either Int or Integer).
You then try and use / on deg, but / doesn't take integral numbers (divide integrals with div):
(/) :: Fractional a => a -> a -> a
The solution is to simply use fromIntegral :: (Integral a, Num b) => a -> b:
toRadians :: Int -> Double
toRadians d = let deg = mod d 360
in (fromIntegral deg)/180 * pi
Seeing Floating a and Integral a in a type signature together always sets off my internal alarm bells, as these classes are supposed to be mutually exclusive - at least, there are no standard numeric types that are instances of both classes. GHCi tells me (along with a lot of other stuff):
> :info Integral
...
instance Integral Integer -- Defined in `GHC.Real'
instance Integral Int -- Defined in `GHC.Real'
> :info Floating
...
instance Floating Float -- Defined in `GHC.Float'
instance Floating Double -- Defined in `GHC.Float'
To see why these classes are mutually exclusive, let's have a look at some of the methods in both classes (this is going to be a bit handwavy). fromInteger in Integral converts an Integral number to an Integer, without loss of precision. In a way, Integral captures the essence of being (a subset of) the mathematical integers.
On the other hand, Floating contains methods such as pi and exp, which have a pronounced 'real number' flavour.
If there were a type that was both Floating and Integral, you could write toInteger pi and have a integer that was equal to 3.14159... - and that's not possible :-)
That said, you should change all your type signatures to use Double instead of Int; after all, not all triangles have integer sides, or angles that are an integral number of degrees!
If you absolutely don't want that for whatever reason, you also need to convert the sides (the a and b arguments) in lawOfCosines to Double. That's possible via
lawOfCosines aInt bInt gamma = sqrt $ a*a + b*b - 2*a*b*(cos (toRadians gamma)) where
a = fromInteger aInt
b = fromInteger bInt
The type signature for toRadians says it takes an Int but returns a Double. In some programming languages, the conversion from one to the other (but not back) happens automatically. Haskell is not such a language; you must manually request conversion, using fromIntegral.
The errors you are seeing are all coming from various operations which don't work on Int, or from trying to add Int to Double, or similar. (E.g., / doesn't work for Int, pi doesn't work for Int, sqrt doesn't work for Int...)

Is it square check

I am trying to write function to check if the argument is square of integer:
isSquare :: Int -> Bool
isSquare x = truncate(sqrt(x)) * truncate(sqrt(x)) == x
When I loading the function I get the error:
Prelude> :load "some.hs"
[1 of 1] Compiling Main ( some.hs, interpreted )
some.hs:2:13:
No instance for (RealFrac Int)
arising from a use of `truncate' at some.hs:2:13-29
Possible fix: add an instance declaration for (RealFrac Int)
In the first argument of `(*)', namely `truncate (sqrt (x))'
In the first argument of `(==)', namely
`truncate (sqrt (x)) * truncate (sqrt (x))'
In the expression: truncate (sqrt (x)) * truncate (sqrt (x)) == x
some.hs:2:22:
No instance for (Floating Int)
arising from a use of `sqrt' at some.hs:2:22-28
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `truncate', namely `(sqrt (x))'
In the first argument of `(*)', namely `truncate (sqrt (x))'
In the first argument of `(==)', namely
`truncate (sqrt (x)) * truncate (sqrt (x))'
Failed, modules loaded: none.
But if i try to execute:
Prelude> truncate(sqrt(9))*truncate(sqrt(9))==9
True
all is fine.
Why I get the error and how to fix it ?
You're getting the errors because of type mismatches. The type of sqrt is sqrt :: Floating a => a -> a, and the type of truncate is truncate :: (RealFrac a, Integral b) => a -> b. The former says that sqrt takes as input any floating-point number, and returns one of the same type as output; the latter says it can truncate any real fractional number1 into any integral number. However, you assert that x is an Int, and an Int isn't a floating-point number. Thus, the second error: "No instance for (Floating Int) arising from a use of `sqrt'". This says that because of sqrt x, it wanted Int to be a floating-point number, but there's no definition for that. Your first error is similar: since sqrt :: Floating a => a -> a, its output is the same as its input, so you're trying to call truncate on an integer. This of course makes no sense, since Int is not a RealFrac, and that's why you get the first error. Fixing this is easy:
isSquare :: Int -> Bool
isSquare x = let x' = truncate $ sqrt (fromIntegral x :: Double) in x'*x' == x
The fromIntegral function has the type fromIntegral :: (Integral a, Num b) => a -> b; it can convert any integral number into any number at all. This is why we need to tell Haskell that we want it to produce a Double; it'd default to that anyway, but it's nice to be clear (though not necessary). Double is an instance both of Floating and RealFrac, so you can sqrt and truncate it. I also rearranged your code a little; the way it is up there is how I'd write it, since this way we only compute the truncation and sqrt once. Also, note that if you remove the type signature, Haskell will infer the more general type isSquare :: Integral a => a -> Bool, since you never assume that x is precisely an Int.
The reason that truncate(sqrt(9))*truncate(sqrt(9))==9 successfully returned True is because of the type of 9. You can ask GHCi to tell you this:
Prelude> :t 9
9 :: (Num t) => t
In Haskell, all integral numeric literals have the type Num t => t (9.0, or any number with a decimal point, has the type Fractional t => t). This means that they can be any kind of number at all, which is a good thing. Otherwise, 9 would have to just be an Int or Integer, and defining new number types—or even using both Int and Integer!2—would be a royal pain. Thus, when you write truncate(sqrt(9)), GHCi determines that 9 must be an instance of Floating (from sqrt) and RealFrac (from truncate), which it defaults to Double, making everything work. This defaulting is standard behavior for numeric types (it's why you could leave out the :: Double in my definition of isSquare), though not for anything else (except in GHCi, which extends it for convenience). Since 9 isn't just an Int, but x is, you don't need to convert 9, but you do need to convert x.
1: The difference between Floating and RealFrac is that, for instance, Complex Double is an instance of Floating but not RealFrac, and Rational is an instance of RealFrac but not Floating. Float and Double are instances of both.
2: In case you haven't come across this, the difference is that Int is finite-precision, and Integer is arbitrary-precision.
You're treating integers as floats. Hence, the types don't match.
Use fromIntegral:
isSquare :: Int -> Bool
isSquare n = truncate(sqrt(x)) * truncate(sqrt(x)) == n
where x = fromIntegral n
Not all that efficient but a cute way of determining if a number is a square, using integer arithmetic only:
isSquare x = x == head (dropWhile (< x) squares)
where squares = scanl1 (+) [1,3..]

Resources