Simple Haskell Average Function Gives Couldn't Match Type Error - haskell

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.

Related

Haskell Float to Int to Float conversion Error

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)

Can I make a polymorphic `mult` function, that takes any numeric type?

I'm learning Haskell. This is the very first program that I've ever wrote and I just thought of making a simple function that returns the product of the given arguments.
mult :: a -> a -> a
mult x y = x * y
When I write it this way, I get an "inferred type" error.
ERROR "uno.hs":5 - Inferred type is not general enough
*** Expression : mult
*** Expected type : a -> a -> a
*** Inferred type : Integer -> Integer -> Integer
It wants me to write it this way:
mult :: Int -> Int -> Int
mult x y = x * y
...which works perfectly fine, but then I wonder... can't this function work on Floats as well?
It can.
mult :: Float -> Float -> Float
mult x y = x * y
--then
mult 4 5 == 20.0
Finally, I wonder:
Can I make a polymorphic mult function, that takes any numeric type?
Why does the parser infers Integrer from a function that also works with other types?
I found no answers so far, yet this seems like a simple question. I'll be grateful for help me.
Short answer: mult :: Num a => a -> a -> a and it picked Integer because it felt like it was a good choice.
Long answer:
mult can't be a -> a -> a because that would mean it works on every type a, including String, Char, Bool, etc. The Num a => part is called a constraint, and it restricts what a can be by requiring that it is an instance of the Num type class. It's like saying "this function works on any type, as long as that type has the properties (has an instance) of this specific type class". The properties for the Num type class are defined in the standard library, linked below.
It's worth noting that the type of (*) itself is Num a => a -> a -> a, and that your function mult could also have been defined as mult = (*).
The reason it told you to use Integer -> Integer -> Integer is because the default for Num is Integer. You should never rely on this being the case, and should instead write out the full, type class constrained type signature.
When you specified the type signature Float -> Float -> Float, the compiler specializes the function to only work on Floats, as you would expect. This resolves the "over-promising" problem arising from a -> a -> a by choosing a specific type for a that the compiler knows has a Num instance.
Read more about type classes here, and the specific definition of Num is documented here and the code is linked on the side of the page. (Not enough rep to post the link directly)

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...)

Resources